当前位置:   article > 正文

Linux | 进度条 | Linux简单小程序 | 超级简单 | 这一篇就够了_linux等待进度条怎么写

linux等待进度条怎么写

进度条—实例示范

在学习了基本的Linux指令,Linux上vim编译器等等之后,我们就来学习写代码喽~

今天就给大家详细讲解一下进度条的编写,需要的效果如下图:

进度条—必备知识

回车和换行

在我们学习编程语言中,经常使用的 [ \n ] ,是什么意思呢?

  • C 语言中有很多字符,而字符大体分为两类:可显字符、控制字符。
  • 控制字符不可显示,例如 \r 和 \n 就是控制字符。

而在我们平时打字时,一行写满了需要换行,其实只根据字面思想来看,换行就是单纯地换行,也就是使光标跳到下一行就是换行。但是这也仅仅只是换行,如下图光标是在行尾的下面,也就是第一行的行尾,所以这是符合我们习惯的。

我们通常的习惯是,在第二段的最左端开始新一行的内容,而要是光标从上一行的行尾,跳到下一行的最左端就应该是两个动作的:换行和回车。

回车就是回到本行的文本行的开头。

所以在编程语言中, [ \n ] 其实两个动作:

  • [ \n ] :换行 + 回车

那么什么是回车呢?

  • [ \r ] :换行 

缓冲区

必备知识点

sleep
  • sleep:Linux 下的休眠函数,单位是秒。头文件为 #include <unistd.h>。

sleep的效果样式,如下图,系统就会休眠3秒。

如下例子,当我们将 [ \n ] 删掉,运行程序我们发现下面会出现:

光标一直闪烁,但是一直都不打印,这似乎是在等待sleep3秒结束之后,因为没有 [ \n ] ,所以也一直等到程序结束时,与shell命令行提示一起打印出来,shell提示符紧跟字符串后面显示。

这反而像是sleep函数先起作用,然后printf函数再从光标处开始打印。

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. int main()
  4. {
  5. //printf("hello world,hello world...\n");
  6. printf("hello world,hello world...");
  7. sleep(3);
  8. return 0;
  9. }

加上 [ \n ] 与 不加 [ \n ] 的区别似乎就是:

  • 加上 [ \n ]:printf执行结束,字符串直接显示出来,然后sleep;
  • 不加 [ \n ]:字符串没有打印出来,先sleep之后,字符串才打印出来。

那么在第二种代码情况下,printf与sleep函数哪个先运行呢?

  • 当然是printf先显示出来;
  • 因为这串字符串并没有换行符,所以打印的字符串必须与命令行的下一行为同一行;
  • C语言执行代码时,永远都是从上往下执行的;
  • 在sleep期间,printf的字符串已经打印出来了,只是这串字符串没有显示出来罢了;
  • 在sleep之后,消息才显示出来。

那么既然printf的字符串已经打印出来了,只是没有显示出来,在sleep期间,字符串是在哪里的呢?

  • 缓冲区

缓冲区理解

缓冲区,可以理解为一块内存空间。

当进行printf打印字符串的时候,字符串被拷贝到了缓冲区,sleep之后,字符串被从缓冲区刷新到显示器,这样就在屏幕上打印出来了字符串了。

一般在程序结束时候或者等到缓冲区满的时候,自动冲刷缓冲区。

缓冲区默认是行刷新的,遇到 [ \n ] 就刷新。

刷缓冲区方式

那么如果不想等到程序结束的时候,直接冲刷缓冲区,如何做呢?

  • [ \n ];
  • 缓冲区已满;
  • 强制刷新。

在打印字符串的后面加上一行强制冲刷缓冲区的代码:

  • fflush(stdout) :刷新缓冲区。
fflush(stdout);                                                                                   
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. int main()
  4. {
  5. //printf("hello world,hello world...\n");
  6. printf("hello world,hello world...");
  7. fflush(stdout);//强制冲刷缓冲区
  8. sleep(3);
  9. return 0;
  10. }

实现倒计时 

光标和显示器匹配,光标在哪里,显示器打印的时候就从哪里开始打印 。

  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. sleep(1);
  10. fflush(stdout);
  11. cnt--;
  12. }
  13. printf("\n");
  14. return 0;
  15. }

 

进度条代码

“ProgressBar.h”头文件

  1. #include "ProgressBar.h"
  2. #include <unistd.h>
  3. //download
  4. double bandwidth=1024*1024*1.0;
  5. void download(double filesize,callback_t cd)
  6. {
  7. double current=0.0;
  8. double bandwidth=1024*1024*1.0;
  9. printf("download done,current:%lf\n",current);
  10. while(current<=filesize)
  11. {
  12. cd(filesize,current);
  13. //从网络中获取数据
  14. current+=bandwidth;
  15. usleep(10000);
  16. }
  17. printf("\ndownload done,filesize:%lf\n",filesize);
  18. }
  19. int main()
  20. {
  21. //ForTest();
  22. //ProgBar(100.0,10.34);
  23. //ProgBar(100.0,20.34);
  24. //ProgBar(100.0,99.98);
  25. //ProgBar(100.0,56.74);
  26. //ProgBar(100.0,69.98);
  27. download(100*1024*1024,ProgBar);
  28. download(50*1024*1024,ProgBar);
  29. download(800*1024*1024,ProgBar);
  30. download(890*1024*1024,ProgBar);
  31. download(67*1024*1024,ProgBar);
  32. download(10*1024*1024,ProgBar);
  33. return 0;
  34. }

“ProgressBar.c”函数文件

  1. #include "ProgressBar.h"
  2. #include <string.h>
  3. #include <unistd.h>
  4. //version 1
  5. //#define Length 101
  6. //#define Style '#'
  7. //const char* lable="|/-\\";
  8. //void ProgBar()
  9. //{
  10. // char bar[Length];
  11. // memset(bar,'\0',sizeof(bar));
  12. // int len =strlen(lable);
  13. // int cnt=0;
  14. // while(cnt<=100)
  15. // {
  16. // printf("[%-100s][%3d%%][%c]\r",bar,cnt,lable[cnt%len]);
  17. // fflush(stdout);
  18. // bar[cnt++]=Style;
  19. // usleep(100000);
  20. // }
  21. // printf("\n");
  22. //}
  23. #define Length 101
  24. #define Style '#'
  25. const char* lable="|/-\\";
  26. //version 2
  27. void ProgBar(double total,double current)
  28. {
  29. char bar[Length];
  30. memset(bar,'\0',sizeof(bar));
  31. int len =strlen(lable);
  32. int cnt=0;
  33. double rate=((current*100.0)/total);
  34. int loop_count=(int)rate;
  35. while(cnt<=loop_count)
  36. {
  37. bar[cnt++]=Style;
  38. }
  39. printf("[%-100s][%.1lf%%][%c]\r",bar,rate,lable[cnt%len]);
  40. fflush(stdout);
  41. }

“Test.c”测试文件

  1. #include "ProgressBar.h"
  2. #include <unistd.h>
  3. //download
  4. double bandwidth=1024*1024*1.0;
  5. void download(double filesize,callback_t cd)
  6. {
  7. double current=0.0;
  8. double bandwidth=1024*1024*1.0;
  9. printf("download done,current:%lf\n",current);
  10. while(current<=filesize)
  11. {
  12. cd(filesize,current);
  13. //从网络中获取数据
  14. current+=bandwidth;
  15. usleep(10000);
  16. }
  17. printf("\ndownload done,filesize:%lf\n",filesize);
  18. }
  19. int main()
  20. {
  21. //ForTest();
  22. //ProgBar(100.0,10.34);
  23. //ProgBar(100.0,20.34);
  24. //ProgBar(100.0,99.98);
  25. //ProgBar(100.0,56.74);
  26. //ProgBar(100.0,69.98);
  27. download(100*1024*1024,ProgBar);
  28. download(50*1024*1024,ProgBar);
  29. download(800*1024*1024,ProgBar);
  30. download(890*1024*1024,ProgBar);
  31. download(67*1024*1024,ProgBar);
  32. download(10*1024*1024,ProgBar);
  33. return 0;
  34. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/614649
推荐阅读
相关标签
  

闽ICP备14008679号