• Linux小程序-进度条


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

    1 简单原理版本

    2 实际工程实践版本

    3 c语言扩展-设计颜色

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

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

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

     

    关于回车换行

    \n :回车+换行

    \r :回车

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

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

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

    进度条蓝图:

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

    process.h

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

    process.c
     

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

    Makefile

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

    main.c

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

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

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

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

    process.h

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

    process.c

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

    main.c

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

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

    process.h

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

    process.c

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

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

    这里使用:

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

    main.c

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

     

  • 相关阅读:
    基于VC++的WEB浏览器的实现
    Linux: Error: EACCES: permission denied Linux 解决方法
    天池AI练习生计划 - 第一期Pyhton入门与实践 正式上线!通关赢取双重礼品!
    halcon 提取图像中的感兴趣区域
    linux jar包class热部署 工具 arthas安装及使用
    【微服务】Ribbon负载均衡
    Prometheus Operator与kube-prometheus之二-如何监控1.23+ kubeadm集群
    如何提升设备投资回报率:预测性维护在制造业的应用
    Docker安装、卸载
    前端性能优化的方法
  • 原文地址:https://blog.csdn.net/weixin_73142957/article/details/133132677