个人主页:🍝在肯德基吃麻辣烫
我的gitee:gitee仓库
分享一句喜欢的话:热烈的火焰,冰封在最沉默的火山深处
文章目录
进度条实现:
本文讲解如何从0到1实现一个进度条小程序。
我们在写作文的时候,写到了一行的结尾,就得另起一行并到开头继续写。
其中,这个另起一行的动作就是"换行"
回到开头的动作就是"回车"
"回车"
这个动作对应的c语言的转义字符是 ‘\r’"换行"
这个动作对应的c语言的转义字符是 ‘\n’
但是,\n其实包含了回车和换行两个动作。
我们的键盘上面的回车键也是同时包含回车和换行两个动作。
1. 认识第一个函数:sleep
sleep(1);
sleep函数的功能是让计算机等待指定秒数(单位:秒)后再继续启动。
知道sleep的功能即可。
还有一个睡眠函数:usleep,它们的功能相同,只不过这个函数的单位是微秒。
1秒 = 1000毫秒
1毫秒= 1000微秒
2.观察缓冲区出现的现象
来看第一段代码出现的现象:
2 #include "process.h" 3 4 int main() 5 { 6 printf("Hello Linux\n"); 7 sleep(2); 8 9 return 0; 10 }
现象:
第二段代码:
2 #include "process.h" 3 4 int main() 5 { 6 printf("Hello Linux"); 7 sleep(2); 8 9 return 0; 10 }
现象:
通过这两段代码以及出现的现象可知:
- 1.第一段代码是直接弹出 “Hello Linux” 字段后两秒,再弹出指令行。
- 2.第二段代码是两秒过后,再打印"Hello Linux",并且指令行是紧随其后的。
问:第一个现象是先执行printf函数还是先执行sleep函数?
实际上,c语言是从上往下扫描代码的,所以一定是先执行printf函数。那么,在sleep两秒期间,printf函数去哪了呢?
一定是被保存起来了。
这个保存的东西,就叫做缓冲区
在c语言有一块内存叫做缓冲区
。
缓冲区是由c语言维护的一块内存空间。
到这里就可以解答第一个现象了,首先执行printf函数,输出Hello Linux,先保存到缓冲区中,2秒后再输出到显示器文件中,由于没有换行,后面则紧跟着指令条。
为什么第二个现象是马上就输出Hello Linux,再睡眠两秒呢?
这是因为'\n'
这个换行符,具有刷新缓冲区的功能。
也就是把缓冲区里面的东西给刷掉,让它走它该走的地方,别停留在缓冲区里面了。
至此我们可以解释第二个现象了:Hello Linux字符串其实是先保存到缓冲区中的,然而
遇到'\n'
这个换行符刷新后,将该字符串输出到了显示器文件中,再执行2秒休眠,这
才是我们看到的东西。
3. 认识第二个函数:fflush
在c程序中会默认打开三个流:标准输入流,标准输出流,标准错误流。
这里只考虑标准输出流,该流的默认数据是stdout
,也就是显示器文件。
fflush函数的功能是:将缓冲区的内容写入到标准输出流。
通俗一点就是将缓冲区的内容打印到屏幕上。
有了这个函数,接下来我们就可以实现进度条小程序了。
了解倒计时
要实现进度条,首先要知道它每一步要输出什么。
首先讲一讲倒计时,我们见过的倒计时是这样的:
这里有一个需要注意的地方:
- 每一个数字都会覆盖上一个数字
就用到开头讲到的'\r'
回车符,每次输出数字后,将光标回到当前行开头,再输出,就能将上一个数字覆盖。
具体代码如下:
2 #include "process.h" 3 4 int main() 5 { 6 int cnt = 9; 7 while(cnt) 8 { 9 printf("%d\r",cnt--); 10 fflush(stdout);11 sleep(1); 12 } 13 return 0; 14 }~
效果如下:
准备工作
知道倒计时怎么走后,我们的进度条的过程是类似的:
输出的过程如上,只是每一次都把数据+1,并输出在当前行,达到一个慢慢增加的效果。(这里为了演示过程,实际上每次输出数据都是输出在同一行)
- 准备一个
buf
数组,数组大小为102
-
- 将数组的所有元素初始化成
'\0'
,这样每次输入都会遇到'\0'
而终止
- 将数组的所有元素初始化成
- 可以给一个小圆圈光标,
const char* lable = "|/-\\"
,意思是:每增加%1,光标就会变化。(这里有两个"\"是为了将转义字符’‘变成一个单纯的’') - 效果如下:
- 当我们输出进度条时(这个进度条的身体由你来决定),我们应该提前保留100个位置给进度条进行输出。也就是:
%s
–>%-100s
- 同理,如开头看到的效果展示,为了输出%(百分号),我们需要两个百分号来输出一个单纯的百分号。
到此,贴出代码,就可以实现进度条啦!
process.h文件
1 2 #include 3 #include 4 #include 5 6 void process();
process.c文件
1 #include"process.h" 2 #define SIZE 102 3 #define BODY '=' 4 #define HEAD '>' 5 6 char bar[SIZE]; 7 const char* lable = "|\\-/"; 8 9 void process() 10 { 11 int cnt = 0; 12 memset(bar,'\0',sizeof(bar)); 13 char c = HEAD; 14 while(cnt<100) 15 { 16 int len = strlen(lable); 17 bar[cnt++] = BODY; 18 if(cnt < 100) 19 bar[cnt] = c; 20 printf("[%-100s][%d%%][%c]\r",bar,cnt,lable[cnt%len]); 21 fflush(stdout); 22 usleep(100000); 23 24 } 25 printf("\n"); 26 }
main.c文件
1 2 #include "process.h" 3 4 int main() 5 { 6 process(); 7 return 0; 8 }
一个进度条就新鲜出炉啦!
今天的文章讲了如何在Linux上实现一个进度条小程序,做这个进度条小程序的核心是理解’\r’和’\n’两个转义字符,以及缓冲区的概念,理解之后,实现起来就不难啦。