上天不给我的,无论我十指怎么紧扣,任然走漏;
给我的,无论我怎么失手,都会拥有!–三毛
1.什么是进度条?
1.1.定义
即计算机在处理任务时,实时的,以图片形式显示处理任务的速度,完成度,剩余任务
未完成任务量的大小,和可能需要处理时间,一般以长方形条状显示.
[dev@localhost bit]$ ./ProcessBar
[ ][
[= ][
[== ][
[=== ][
[==== ][
[===== ][
[====== ][
[======= ][
[======== ][
[========= ][
[==========
...
1.2进度条的实现条件
(1) 由#或者=组成的进度条在一行上由少到多一个个增长,直到增加到已设定的值;
(2) 随着进度条的增长,在该行的结尾显示变化着的进度百分比;
(3) 在进度条增长的过程中,有一光圈不停转动,直到进度条完成;
(4) 将进度条变为彩色的。
2.进度条的实现
2.1程序代码
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <string.h>
4
5 int main(){
6 int i=0;
7 char bar[102];
8 memset(bar,0,sizeof(bar));
9 const char* lable = "|/-\\";
10 while(i <= 100){
11 printf("[%-100s][%d%%][%c]\r",bar,i,lable[i%4]);
12 fflush(stdout);
13 bar[i++] = '='; 14 usleep(60000);
15 }
16 printf("\e[0m \n");
17 return 0;
18 }
- 运行结果
[====================================================================================================][100%][|]
[dev@localhost bit]$
- 使用makefile和make进行编译
1 ProcessBar:ProcessBar.c
2 gcc $^ -o $@
3 vfork:vfork.c
4 gcc $^ -o $@
2.2代码剖析
2.2.1
(1)进度条是有#或者组成,且不断增加,所以将这些#放在一个字符数组中,这里可以人为设定数组的大小,初始时,数组中只有一个#。
char bar[102] = "#";
(2)每循环一次,往数组中增加一个#,增加后就输出,达到增长的效果。
(3)但是每次输出必须在同一行输出,所以,这里就需要用到\r。(与\n进行区别)
\r:回车,将光标的位置重新定位在一行的开头
\n:换行,将光标的位置定位在下一行的同一位置
\r\n:回车换行,将光标位置定位在下一行开头
(4)同时,这里还存在一个输出缓冲区的问题,printf输出的内容会先放在输出缓冲区中,然后遇到下列几种情况之一才会输出到屏幕:
1)遇到‘\n’;
2) 遇到输入函数(scanf,getchar等);
3)用fflush(stdout)自动清空输出缓冲区
4) 遇到程序结束 ;
5) 缓冲区满
而我们需要的是,每进行一次循环在屏幕上输出一次。综合上述几种情况,选择用fflush(stdout)的方法来输出缓冲区。即printf一次,清空一次缓冲区。在循环语句中增加一条代码:
fflush(stdout);
(5)由于程序运行的速度非常快,我们可能只能看到最终的输出结果,而捕捉不到每次的输出结果,所以,每输出一次,令程序睡眠0.1s,这里需要用到函数usleep:
usleep(num);//num的单位是微妙,注意sleep函数的单位是秒
所以,在循环语句中在增加一条语句:
usleep(100000);//需引入头文件<unistd.h>
完成上述几点后,就可以初步打印出一条变化的进度条了。
2.2.2打印百分比
只需在进度条的末尾不断打印变化着的百分比即可,这里可以再循环中进行体现。因为百分比打印的位置固定,永远在进度条的末尾,且进度条要从左开始向右进行打印,所以打印进度条的格式为:%-100s,他表示的意思是,从左向右打印100个字符,如果实际的字符不够100个,就用空格代替。代码修改如下:
printf("[%-100s][%d%%][%c]\r",bar,i,lable[i%4]);
2.2.3 打印转动的光圈
光圈可以用“—,|,/,\”不断的交替打印来实现。所以,定义容纳这些字符的数组:
9 const char* lable = "|/-\\";
2.2.4 实现彩色的进度条
通过转义序列设置终端显示属性时,可采用以下格式:
\033[Param{;Param;…}m 或 \e[Param{;Param;…}m
其中,\033[或\e[为引导转义序列,Param为属性项,{ }表示可选,多个选项间用分号间隔。
m表示设置属性并结束转义序列
常见的属性项为(具体可根据:man console_codes命令查询):
显示序列:
\033[0m 关闭转义序列
\033[1m 粗体或高亮
\033[5m 闪烁
前景颜色序列:
\033[30m 黑
\033[31m 红
\033[32m 绿
\033[33m 黄
\033[34m 蓝
\033[35m 洋红
\033[36m 青
\033[37m 白
背景颜色序列:
与前景颜色对对应,前景色是30+,背景色是40+
3.程序中重要的部分解读
3.1 makefile
使用makefile自动化编译可以增加效率,尤其在项目源文件有若干个.c 和.h 文件的时候,这一特点更为明显。
第一行:依赖关系;
第二行:依赖方法,(注意必须以Tab键开头,刚开始使用makefile一定要注意细节)。
3.2 memset
对各种类型的数组进行初始化,避免出现野值。正确用法如下:
- 1.可以用任何值来初始化char数组,比如:memset(arr,‘a’,10);
- 2.可以用0来初始化任何类型数组,比如:memset(arr,0,sizeof(arr))。