Linux小程序-进度条

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

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 }        

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值