进度条小程序
认识缓冲区与刷新策略
在外面运行生成的程序,发现输出了hello,5s之后程序才结束。
那么在程序里将\n换行删掉在观察一下:
我们在命令行中肉眼发现的现象是先睡眠了5s,之后才输出的hello。
那么是先执行了第6行,在执行第5行吗。
不是的,在任何语言,除了if语句,函数,循环,执行顺序都是从上至下的。那么w为什么这个现象是先睡眠5s在输出呢。这就需要提到开始的缓冲区概念。
原因:
当代码执行prinf语句,把printf中的字符串加载到程序的缓冲区(内存)当中,然后执行sleep,休眠结束,刷新缓冲区,然后才输出字符串内容。
刷新策略:
- 行刷新,遇到/n刷新,输出内容,这就是第一个代码为什么先输出的在睡眠。
- 程序结束
- 强制刷新,
fflush(File* stream)
,当文件关闭的时候
程序默认情况下打开3个文件与人交互。键盘,显示器,显示器。分别对应stdin(标准输入),stdout(标准输出),stderr(标准错误)。
重温/r与/n
在平常我们所说的换行是包括回车换行的(先换行在回车)但严格来说这是两个概念。
这个竖杠就很好地帮我们区分了概念
编写代码
先写清楚声明,以及定义一个101大小的数组,因为要把这个数组当字符串用所以要多开一个给’\0’。
而我们进度条的#号要一直增加,每次都在后面加太麻烦了,我们把数组全部用memset内存函数置成’\0’。
由于换行会变成,我们想要的是在一行不断的变化。所以加\r,回车回到第一行
括号这样很难看,想要直接预留在右边,需要prinf里面加100.留100个空位,由于程序默认右对齐,所以要变成-100
但是加了回车,由于有睡眠10毫秒,prinf会把字符串加到缓冲区,程序结束才输出。所以用强制刷新。
继续给进度条加元素,多少个#对应的是当前的百分之多少,%在prinf中则作为格式控制符,所以需要加两个百分号%%。
就达到了这样的效果
最后再加一个斜杠逆时针旋转。我们创建一个lable字符串,由于\有特殊含义所以我们要写成\代表他本身。
然后怎么再循环里动态输出它,让他产生变化呢。我们可以通过模4就可以让他重复打印数组内字符的内容。
就可以完成了。
proc.c代码
1 #include"proc.h"
2
3 void proc()
4 {
5
6 char bar[NUM];
7 memset(bar,'\0',sizeof(bar));
8 int i=0;
9 const char* lable="|/-\\";
10 while(i<100)
11 {
12 bar[i++]='#';
13 printf("[%-100s][%d%%][%c]\r",bar,i,lable[i%4]);
14 fflush(stdout);
15 usleep(10000);
16
17 }
18 printf("\n");
19
20 }