开始今天的内容之前,我们需要了解几个知识点:
第一点:缓冲区
看下面一段代码(Linux下运行程序)
对比上边的代码,似乎相差不大,但是运行结果却千差万别:A图代码运行结果---先输出“hello”,停3秒之后程序运行完毕;B图代码运行结果---执行程序后会先停3秒,然后再输出“hello”。差异如此大的原因与我们所学习的有关于缓冲区的知识是有关系的。
首先我们需要知道缓冲区的三种缓冲方式:全缓冲、行缓冲、无缓冲。对于一个shell中运行的程序,默认的输出方式就是控制台,并且控制台使用的是行缓冲的方式,也就是说当遇到换行符 '\n' 或者写满一行后后,就刷新一遍缓冲区的内容。printf函数在输出数据时也不是直接内容输出到显示器上,而是先将内容输入到缓冲区,当缓冲区的内容写满一行或者遇到换行符后就会刷新一次,此时才将缓冲区的内容刷新到显示器上。
理解这点后,我们再来分析上面的两个例子:A代码中,“hello”后边有一个换行符,因此遇到 '\n' 后系统会先将这一行的内容刷新出来,也就是“hello”,然后程序就会继续执行下一条,sleep(3)的意思就是把该进程挂起3秒,这里是为了方便分析这两种情况加的。而在B代码中,“hello”会先被写入到缓冲区,此时没有换行符,会继续执行下一条指令,当程序结束时会强制刷新缓冲区,输出缓冲区的内容。(在Linux中,我们也可以使用 fflush(stdout) 强制刷新缓冲区。)
第二点:换行和回车
换行:\n,光标往下移一行,但并不一定在下一行的头部
回车:\r,将光标重新回到这一行的开头
我们在键盘上敲下“Enter'”键后其实是做了两步的:先换行,再回车。
实现进度条时,我们就利用了这个原理,并不是真的让进度条动起来,而是每次往写入的数组里比上次多写一个字符,就会感觉在往前动一样。
绕了这么久,终于可以回到正题上了。让我们先看一个实现以后的效果图吧:
对上图左一个解释:前面[=== .....] 就表示进度条,紧接着的[96%]表示进度条此时下载东西的百分比(更方便我们来了解进度),最后的[-]是一个标志,当进度条不进行的时候方便分析是进度条卡死还是程序崩了。
因此实现进度条所需要的元素有:
1.字符数组pro:存放进度条的内容 ’=‘ ,进度条往后走一个,就多一个 ’‘
2.字符串spin:组成“-\|/”,模拟成转圈的样子(就像我们在下载东西没网时中间转的那个圈圈。)
3.注意:进度条的数字显示为0%时,进度条内不能有 ‘=’;
4.输出字符数组pro时,我们会用到格式控制符“%s”,但这样不能给我们预留足够空间来填充 ‘=’ ,达不到视觉上的效果,因此这里应该使用“%100s”;除此之外,我们应该进一步写成这个样子“%-100s”,这样打印出来的效果就是 ‘=’ 从左往右走的。
下面是我实现的进度条的代码部分probar.c:
最终的效果图: