在Linux下实现简易进度条

本文将要概述

  1. printf的缓冲区问题;
  2. \r和\n的区别;
  3. 如何实现一个简易的进度条;

奇怪的现象

进度条是安装和下载软件中常见的部分,它可以表示软件安装或下载了多大,能给客户一种直观的感受,今天我们就来实现一个简易的进度条,基本构思是这样的,我们定义一个大小为102的字符数组,其中100个用来存储‘#’,每跑了进度条的1%它就会在字符数组中增长一个该符号。还有两块空间用于存放’\0’,和防止死循环问题(这是因为控制循环的变量被定义在数组的后面一块空间,对数组访问造成了越界的话很有可能修改这块空间的值,从而造成不可预料的后果)所以我们多开辟一块空间,避免这种情况的发生。

程序的思路是这样的,每一次循环都往字符数组中的当前位置写入’#’,并将控制循环变量+1,在写入’#’的下一个人位置写入’\0’,防止打印字符数组时出现乱码。循环次数控制在100次,每输入1行后我们输入\r对其清空,由于延时时间段和人眼的视觉暂留效应,你会看到进度条是一个一个#增长的。
理论上你应该看到这样的效果
[# ]
[## ]
.
.
.
[############################## ]
[############################### ]
[################################]
代码如下
这里写图片描述
由于本人这里没有截动态图的软件,当程序写好后通过gcc编译成可执行文件直接执行你会看到进度条并不会像你想象的那样增长。它是一次好几个#号的增长直到#增长到100个位置。

这是为什么呢????????
下面我们就来揭秘一下这个现象的原因!!!!!

printf的缓冲区问题

出现上面这种原因首先肯定是由于\r的效果,我们再来修改一下程序,把\r换成\n看看会出现什么现象。
这里写图片描述

真是不吹不黑,咱们来看一下效果,特别是#每次的增长个数;
这里写图片描述

这时我只截图一部分的效果。

结合着\n和\r的现象我们来引入一个知识点,printf的缓冲区问题

出现上面的两种情况,是因为printf是一个行缓冲函数,当我们用printf打印时,先写到缓冲区,如果缓冲区没有被则先不打印到屏幕上,直到缓冲区刷新了后才会输出到屏幕上。

刷新缓冲区只要满足下面任意一个条件即可:
1. 缓冲区填满
2. 写入的字符中有‘\n’
3. 调用fflush手动刷新缓冲区
4. 调用scanf要从缓冲区中读取数据时,也会将缓冲区内的数据刷新

可见每次我们写入\r是不能够刷新缓冲区的,只会等缓冲区慢后才会将字符串打印到屏幕上,那么我们想要实现一个进度条,就不能够用\n字符,我们必须要在一行上对缓冲区进行刷新,于是我们每次写入到缓冲区时,都用fflush函数刷新一下缓冲区,问题是不是就能解决了呢?实践出真知,还是让我们修改下代码看看结果吧!

事实是大功告成了!!!
这里写图片描述

所修改的代码
这里写图片描述
由于printf是输出缓冲区,所以我们需要刷新下stdout,我们可以男人(man)一下看看这个stdout是干什么的。
这里写图片描述

总结

好了,今天我们主要谈到了printf的输出缓冲区的问题,进度条的实现依赖于每次写进缓冲区后都要刷新缓冲区,使缓冲区中的字符输出到屏幕上。

Makefile的使用:http://blog.csdn.net/bit_clearoff/article/details/53966718

vim编辑器http://blog.csdn.net/bit_clearoff/article/details/53884356

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章