Linux小步伐:进度条

打印 上一主题 下一主题

主题 582|帖子 582|积分 1746

目次
一、换行与回车
二、缓冲区
三、倒计期间码
四、进度条实现


实现进度条步伐,起首需要两个预备知识:
1.换行与回车
2.缓存区
一、换行与回车

我们通常使用\n作为换行符,但现实上\n是换行+回车两种效果的结合,因此我们需要区分一下换行与回车的区别:
换行是从上一行的第n个位置跳转到下一行的第n个位置;回车则是从某一行的第n个位置跳转到该行的第一个位置
\r表示回车,\r\n表示回车+换行(只有\n和\r一起使用时,\n才表示换行),\n表示回车+换行
二、缓冲区

先对比两段代码,唯一的区别就是printf函数输出时有没有加上\n
运行时,代码1会先输出内容,再等候3秒;代码2会先等候3秒,再输出内容
由此引入问题:代码2先等候3秒,但是步伐运行时一定是按次序实行代码,也就是说是printf函数先实行,那么再等候的这3秒内,printf函数输出的数据在哪里呢?
答案是:在缓冲区,printf输出的数据会被拷贝到缓冲区,在步伐运行结束的时候会冲刷缓冲区,此时printf输出的数据才会显示出来
  1. //第一段代码
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. int main()
  5. {
  6.    printf("hello makefile\n");
  7.    sleep(3);                                                                                                      
  8.    return 0;
  9. }
  10. //第二段代码
  11. #include <stdio.h>
  12. #include <unistd.h>
  13. int main()
  14. {
  15.    printf("hello makefile");
  16.    sleep(3);                                                                                                      
  17.    return 0;
  18. }
复制代码
缓冲区的三种冲刷方式:
(1)\n冲刷
printf输出时加上\n,printf输出的数据被拷贝到缓冲区,\n会主动冲刷缓冲区
(2)fflush强制冲刷
我们可以调用fflush函数强制冲刷缓冲区,包罗在头文件<unistd.h>
(3)步伐运行结束冲刷
步伐运行结束时,也会主动冲刷缓冲区
三、倒计期间码

根据上面的明白,我们可以实现一个简单的倒计期间码
C语言在输出时会默认打开3个标准输入输出流,分别为stdin、stdout、stderr,此中stdin为键盘输入,stdout和stderr都是显示器输出
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. int main()
  4. {
  5.    int cnt=9;
  6.    while(cnt>=0)
  7.    {                                                                             
  8.      printf("倒计时:%d\r",cnt);                     
  9.      fflush(stdout);              
  10.      sleep(1);                                                                                                     
  11.      cnt--;                                    
  12.    }                                 
  13.    printf("\n");//最后一行\n的作用是防止程序最后的输出倒计时:0 被命令行提示符覆盖
  14.                 //因为\r回车,光标回到了倒计时:0的前面,此时再输出命令行提示符一定会覆盖倒计时:0
  15.                 //而使用\n换行后,缓冲区的光标就会跳到 倒计时:0 的下一行,此时输出命令行提示符就不会覆盖倒计时:0
  16.    return 0;                             
  17. }      
复制代码
如果cnt初始值为10,则始终有一个0无法被覆盖,此时我们需要将%d改为%2d,使得输出字段的最小宽度为2,小于2则在左侧用空格补齐,这样就能覆盖掉0了
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. int main()
  4. {
  5.    int cnt=10;
  6.    while(cnt>=0)
  7.    {                                                                             
  8.      printf("倒计时:%2d\r",cnt);                     
  9.      fflush(stdout);              
  10.      sleep(1);                                                                                                     
  11.      cnt--;                                    
  12.    }                                 
  13.    printf("\n");
  14.    return 0;                             
  15. }      
复制代码
四、进度条实现

  1. //progress_bar.h
  2. void progress_bar();
  3. //progress_bar.c
  4. #include <stdio.h>
  5. #include "progress_bar.h"
  6. #include <memory.h>
  7. #include <unistd.h>
  8. #define out '#'
  9. void progress_bar()
  10. {
  11.     char rotate[4] = {'|', '/', '\\', '-'};
  12.     char arr[101];
  13.     memset(arr, '\0', 101);
  14.     int cnt = 0;
  15.     while (cnt < 100)
  16.     {
  17.         arr[cnt] = out;
  18.         printf("[%-100s][%d%%][%c]\r", arr, cnt + 1, rotate[cnt % 4]);
  19.         fflush(stdout);
  20.         usleep(20000); // usleep,单位为微秒
  21.         cnt++;
  22.     }
  23.     printf("\n");
  24. }
  25. //main.c
  26. #include <stdio.h>
  27. #include "progress_bar.h"
  28. int main()
  29. {
  30.     progress_bar();
  31.     return 0;
  32. }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

北冰洋以北

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表