Linux小程序-进度条

2023-09-21 23:28:48

进度条我将实现三个版本:

1 简单原理版本

2 实际工程实践版本

3 c语言扩展-设计颜色

首先我们需要有一些前置知识:关于行缓冲区和回车换行

行缓冲区:c/c++语言会针对标准输出给我们提供默认的缓冲区,这次的角色是输出缓冲区

输出的内容不会立马显示,而是放置在输出缓冲区内,只有当缓冲区刷新时我们才会看到输出的内容,而我们平时打印内容喜欢在其后加上\n ,其实\n就是一种刷新的策略(行刷新)

 

关于回车换行:

\n :回车+换行

\r :回车

编写进度条我们可以这样做:

每次多打印一个字符,且从头开始打印,形成覆盖效果

这里就需要用\r了,每打印完字符串后又重新回到开头,覆盖式地打印比前字符串多一个字符的字符串,因为每次打印都在同一行,视觉效果上就是进度条加载的模样了

进度条蓝图:

进度条版本1(简单原理版)

process.h

  1 #pragma once 
  2 
  3 #include<stdio.h>
  4 #include<string.h>
  5 #include<unistd.h>
  6 
  7 #define SIZE 101
  8 #define MAX_RATE 100
  9 #define STIME 1000*40//休眠时间 ,1秒=1000000微秒,usleep以微妙为计时单位,但是1秒可能太慢了,我们将速度稍微调快一点
 10 #define STYLE '#'
 11 
 12 void process_v1();  

process.c
 

  1 #include"process.h"
  2 
  3 const char *str = "|/-\\";
  4 
  5 void process_v1()
  6 {
  7     int num = strlen(str);
  8     char bar[SIZE];
  9     memset(bar,'\0',sizeof(bar));
 10     int rate = 0;
 11     while(rate<=MAX_RATE)
 12     {
 13         printf("[%-100s][%d%%][%c]\r",bar,rate,str[rate%num]);//左对齐
 14         fflush(stdout);//刷新输出缓冲区
 15         usleep(STIME);//休眠(停顿一下)
 16         bar[rate++] = STYLE;
 17     }
 18     printf("\n");                                                                                                                     
 19 }

Makefile

  1 process:process.c main.c                                                                                                              
  2     gcc $^ -o $@
  3 
  4 .PHONY:clean
  5 clean:
  6     rm -f process

main.c

  1 #include"process.h"
  2 
  3 int main()
  4 {
  5     process_v1();                                                                                                                     
  6     return 0;
  7 }

 进度条版本2(实际工程实践版本)

版本1的进度条是一次就打印完毕,不能平滑的与实际场景相结合,版本2就与实际场景相结合了,

做到:每下载一点就根据rate打印一次

process.h

  1 #pragma once 
  2 
  3 #include<stdio.h>
  4 #include<string.h>
  5 #include<unistd.h>
  6 
  7 #define SIZE 101
  8 #define MAX_RATE 100
  9 #define STIME 1000*40
 10 #define STYLE '#'
 11 #define TARGET_SIZE 1024*1024//下载文件的总大小为1MB
 12 #define DSIZE 1024*10//每次下载的大小
 13 void process_v1();
 14 void process_v2(int);  

process.c

 24 void process_v2(int rate)
 25 {
 26     int num = strlen(str);
 27     static char bar[SIZE] = {0}; //设置成静态的数组,使之能保持上次的结果                                                                                                     
 28     if(rate>=0 &&  rate<=MAX_RATE)
 29     {
 30         printf("[%-100s][%d%%][%c]\r",bar,rate,str[rate%num]);
 31         fflush(stdout);
 32         bar[rate] = STYLE;
 33     }
 34     if(rate==MAX_RATE)
 35     {
 36         memset(bar,'\0',sizeof(bar));
 37     }
 38 }

main.c

  1 #include"process.h"
  2 
  3 void download()//下载函数
  4 {
  5     int total  = 0;
  6     int target = TARGET_SIZE;//下载文件的总大小
  7     while(total<=target)
  8     {
  9         usleep(STIME);//休眠时间来模拟本轮下载花费的时间
 10         total+=DSIZE;
 11         process_v2(total*100/target);//显示下载进度
 12     }
 13     printf("\n");
 14 
 15 }
 16                                                                                                                                       
 17 int main()
 18 {              
 19     download();
 20     return 0;
 21 }
~

进度条版本3( c语言扩展-设计颜色)

process.h

  1 #pragma once 
  2 
  3 #include<stdio.h>
  4 #include<string.h>
  5 #include<unistd.h>
  6 
  7 #define SIZE 101
  8 #define MAX_RATE 100
  9 #define STIME 1000*40
 10 #define STYLE '#'
 11 #define TARGET_SIZE 1024*1024
 12 #define DSIZE 1024*10
 13 #define STYLE_BODY '='
 14 #define STYLE_HEADER '>'                                                                                                              
 15 typedef void (*callback_t)(double);//函数指针类型callback_t
 16 void process_v1();
 17 void process_v2(int);
 18 void process_v3(double);

process.c

 43 void process_v3(double rate)
 44 {
 45     int num = strlen(str);
 46     static char bar[SIZE] = {0};
 47     static int cnt = 0;
 48     if(rate>=0 &&  rate<=MAX_RATE)
 49     {
 50         cnt++;
 51         cnt = cnt>=num? 0:cnt;
 52         printf("加载中……[%-100s][%.1f%%][%c]\r",bar,rate,str[cnt]);//未加上颜色
 53         fflush(stdout);
 54         if(rate<=MAX_RATE)
 55         {                                                                                                                             
 56             bar[(int)rate] = STYLE_BODY;
 57             bar[(int)rate+1] = STYLE_HEADER;
 58         }
 59 
 60     }
 61 }

若要加上颜色可以自己去搜索c语言颜色的代码,根据喜好自行变换即可

这里使用:

printf("加载中...[\033[33;44m%-100s\033[0m]][%.1f%%][%c]\r",bar,rate,str[cnt]);   

main.c

 19 void download2(callback_t cb)
 20 {
 21     int total  = 0;
 22     int target = TARGET_SIZE;
 23     int cnt = 100;
 24     while(total<=target)
 25     {
 26         usleep(STIME);//模拟下载花费的时间
 27         total+=DSIZE;
 28         double rate = total*100.0/target;
 29         if(rate>50.0 && cnt)//模拟下载中进度条的停顿,但仍在下载
 30         {
 31             total = target/2;
 32             cnt--;
 33         }
 34         cb(rate);//回调函数
 35     }
 36     cb(MAX_RATE);
 37     printf("\n");
 38 
 39 }
 40 
 41                              
 42 int main()        
 43 {              
 44     download2(process_v3);
 45     return 0;      
 46 }        

 

更多推荐

Prometheus-Rules 实战

文章目录1noderules2nginxrule2.1Nginx4xx错误率太多2.2Nginx5xx错误率太多2.3Nginx延迟高3mysqlrule3.1MySQL宕机3.2实例连接数过多3.3MySQL高线程运行3.4MySQL从服务器IO线程没有运行3.5MySQL从服务器SQL线程没有运行3.6MySQL复

Nginx负载均衡详解

一、负载均衡介绍1、负载均衡的定义单体服务器解决不了并发量大的请求,所以,我们可以横向增加服务器的数量(集群),然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡。负载均衡的意思是在服务器集群中,需要有一台服务器作为调度者,客

第二章 进程与线程 十二、进程同步与进程互斥

目录一、进程同步1、定义二、进程互斥1、定义2、四个部分3、原则一、进程同步1、定义进程同步是指在多个进程之间协调执行顺序的一种机制,使得进程按照一定的顺序执行,以避免出现不一致的情况。常见的实现方式有信号量、管程、屏障等。二、进程互斥1、定义进程互斥是指在多个进程之间共享资源时,为了避免多个进程同时访问该资源而出现冲

利用亚马逊 云服务器 EC2 和S3免费套餐搭建私人网盘

网盘是一种在线存储服务,提供文件存储,访问,备份,贡献等功能,是我们日常中不可或缺的一种服务。很多互联网公司都为个人和企业提供免费的网盘服务。但这些免费服务都有一些限制,比如限制下载速度,限制文件大小,不能多人同时管理,不能实现一些定制化功能。如果想取消这些限制,就要付费。现在我给大家介绍一种免费,且功能无限制的私人网

ActiveMQ、RabbitMQ、RocketMQ、Kafka区别

一、消息中间件的使用场景消息中间件的使用场景总结就是六个字:解耦、异步、削峰1.解耦如果我方系统A要与三方B系统进行数据对接,推送系统人员信息,通常我们会使用接口开发来进行。但是如果运维期间B系统进行了调整,或者推送过程中B系统网络进行了调整,又或者后续过程中我们需要推送信息到三方C系统中,这样的话就需要我们进行频繁的

数据结构与算法:排序算法(2)

目录堆排序使用步骤代码实现计数排序适用范围过程代码实现排序优化桶排序工作原理代码实现堆排序二叉堆的特性:1.最大堆的堆顶是整个堆中的最大元素2.最小堆的堆顶是整个堆中的最小元素以最大堆为例,如果删除一个最大堆的堆顶(并不是完全删除,而是跟末尾的节点交换位置),经过自我调整,第2大的元素就会被交换上来,成为最大堆的新堆顶

Ae 效果:CC Wide Time

时间/CCWideTimeTime/CCWideTimeCCWideTime(CC宽泛时间)能够将前后不同时间的帧叠加在一起,从而创建移动物体的运动轨迹,实现重影、运动模糊、光影跟随等效果。可以配合其它的效果使得本效果有更多的可控性。比如,“CCComposite”效果可使得原始内容清晰可见。“色调”Tint效果可改变

Kotlin Android中错误及异常处理最佳实践

KotlinAndroid中错误及异常处理最佳实践Kotlin在Android开发中的错误处理机制以及其优势Kotlin具有强大的错误处理功能:Kotlin提供了强大的错误处理功能,使处理错误变得简洁而直接。这个特性帮助开发人员快速识别和解决错误,减少了调试代码所需的时间。Kotlin的错误处理特性:Kotlin具有一

Windows下,快速部署开发环境,第三方库管理,以及项目迁移工具介绍

对于在windows下做c++开发的同学,你是否有以下痛点?:1.每次构建c++项目,搭配第三方库环境,都要不停的include,lib,dll等配置,如果4-5个还好,要是10几个...人都麻了...2.一个环境也无所谓,问题x64/32位系统,Debug,Release都要配置一遍..每次配置完成后,还要运行检测.

Hadoop初识及信息安全(大数据的分布式存储和计算平台)

目录什么是HadoopHadoop的特点Hadoop优点Hadoop的缺点Hadoop的重要组成信息安全什么是HadoopHadoop是一个适合大数据的分布式存储和计算平台。Hadoop的广义和狭义区分:狭义的Hadoop:指的是一个框架,Hadoop是由三部分组成:HDFS:分布式文件系统--》存储;MapReduc

虚拟IP技术

1.说明虚拟IP(VirtualIPAddress,简称VIP)是一个未分配给真实弹性云服务器网卡的IP地址。弹性云服务器除了拥有私有IP地址外,还可以拥有虚拟IP地址,用户可以通过其中任意一个IP(私有IP/虚拟IP)访问此弹性云服务器。同时,虚拟IP地址拥有私有IP地址同样的网络接入能力,包括VPC内二三层通信、V

热文推荐