Linux中实现一个简单的进度条
2017-01-01 13:48
204 查看
说起进度条,其实大家常常见到,比如说你在下载视频或文件的时候,提示你当前下载进度的就是我们今天要说的进度条,进度条的模拟实现是挺简单的,但是要做的比较实用还是需要注意很多地方的,下来我就一步步的深入分析一下进度条得实现。
1.起初写下了这样的代码,解释以下几点:
1>首先我们需要将[ ]固定在左右两边,中间预留下空间,然后用“=”进行填充。这里printf("[%-100s]\r",str); 格式化输出,[b]‘-’表示左对齐,100表示固定列宽,然后‘\r’ 表示回车,即每次打印完使光标回到最开始位置
[/b]再明确一下,‘\n’和‘\r’这两个概念:
‘\n’表示换行,换到当前行的下一行,即光标指向下一行最开始的位置;'\r'指回车,即光标回到最开始位置。
2>如果不加睡眠时间,结果一下就全打印出来了,但我们想让它稍微慢一点,毕竟是进度条嘛,而Linux系 统下默认sleep时间单位为秒(s),这样的话又觉得间隔时间太长了,于是就有了usleep,它是以微妙计的, 其头文件在#include
<unistd.h>下,这些信息不明白了就man一下;
3>如下代码我们在观察现象时会发现是隔0.1s在显示,但是它却是一段一段显示的,这就让人很是郁闷了, 最后才发现是printf的原因,printf是先将要输出的内容写到缓冲区里,然后再刷新。
首先介绍一下UNIX里面关于标准IO的几种缓冲机制:
<3.1>全缓冲 ,全缓冲指的是系统在填满标准IO缓冲区之后才进行实际的IO操作;注意,对于驻留在磁盘上的文件来说通常是由标准IO库实 施全缓冲。
<3.2>行缓冲,在这种情况下,标准IO在输入和输出中遇到换行符时执行IO操作;注意,当流涉及终端的时候,通常使用的是行缓冲。
<3.3>无缓冲,无缓冲指的是标准IO库不对字符进行缓冲存储;注意,标准出错流stderr通常是无缓冲的。
printf是一个行缓冲函数,先写到缓冲区,满足条件后,才将缓冲区刷到对应文件中,刷缓冲区的条件如下:
(1)缓冲区填满;
(2)写入的字符中有‘\n’ ,'\r';
(3)调用fflush手动刷新缓冲区;
(4)调用scanf要从缓冲区中读取数据时,也会将缓冲区内的数据刷新;
满足上面4个条件之一缓冲区就会刷新
下面是代码实现:
![](http://img.blog.csdn.net/20170101124214910?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjk1MDMyMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
看一下效果图:
![](http://img.blog.csdn.net/20170101123207918?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjk1MDMyMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
2.知道了上面按一段一段显示的原因,下面我们就来改进一下它,通过fflush这个函数就可以解决这个问题。
fflush用于清空缓冲流,这样就会立刻输出所有在缓冲区的内容,也就能即时刷新,这样刚好就满足了进度条的实时性。
![](http://img.blog.csdn.net/20170101125047213?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjk1MDMyMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
下面是效果展示:
![](http://img.blog.csdn.net/20170101125329356?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjk1MDMyMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
3.上面基本达到了我们想要的效果,但是还是不好,在你下载文件的时候人家就有一个百分比来提示你下载了多少了,而我们这只有一个进度条,前进了多少还得自己估计,这样多不好啊,所以我们也来实现一下这种方式。
![](http://img.blog.csdn.net/20170101130345353?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjk1MDMyMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
效果图:
![](http://img.blog.csdn.net/20170101125929150?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjk1MDMyMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
4.上面实现的看似都有了该有的效果,但是我们还是会感觉有些欠缺,比如有时候进度条会有停止不前的时候,这个时候我们很难知道程序是在继续运行还是卡住了,下面我通过一种动态旋转的图标对其进行优化。
旋转图标自己可以定,“- \ \ | /”或“| / - \ \”都可以
![](http://img.blog.csdn.net/20170101131646120?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjk1MDMyMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
效果图:
![](http://img.blog.csdn.net/20170101131318917?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjk1MDMyMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20170101131422260?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjk1MDMyMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
5.最后再提一点,我在运行代码时就用了两个命令,make 和./Proc,那是因为我提前就编写了一个Makefile文件,这样就方便了我们运行代码。
下面就来看一下Makefile文件:
![](http://img.blog.csdn.net/20170101133914633?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjk1MDMyMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
作为一个好习惯,记得每次在执行完./Proc后make clean一下
![](http://img.blog.csdn.net/20170101134138441?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjk1MDMyMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
1.起初写下了这样的代码,解释以下几点:
1>首先我们需要将[ ]固定在左右两边,中间预留下空间,然后用“=”进行填充。这里printf("[%-100s]\r",str); 格式化输出,[b]‘-’表示左对齐,100表示固定列宽,然后‘\r’ 表示回车,即每次打印完使光标回到最开始位置
[/b]再明确一下,‘\n’和‘\r’这两个概念:
‘\n’表示换行,换到当前行的下一行,即光标指向下一行最开始的位置;'\r'指回车,即光标回到最开始位置。
2>如果不加睡眠时间,结果一下就全打印出来了,但我们想让它稍微慢一点,毕竟是进度条嘛,而Linux系 统下默认sleep时间单位为秒(s),这样的话又觉得间隔时间太长了,于是就有了usleep,它是以微妙计的, 其头文件在#include
<unistd.h>下,这些信息不明白了就man一下;
3>如下代码我们在观察现象时会发现是隔0.1s在显示,但是它却是一段一段显示的,这就让人很是郁闷了, 最后才发现是printf的原因,printf是先将要输出的内容写到缓冲区里,然后再刷新。
首先介绍一下UNIX里面关于标准IO的几种缓冲机制:
<3.1>全缓冲 ,全缓冲指的是系统在填满标准IO缓冲区之后才进行实际的IO操作;注意,对于驻留在磁盘上的文件来说通常是由标准IO库实 施全缓冲。
<3.2>行缓冲,在这种情况下,标准IO在输入和输出中遇到换行符时执行IO操作;注意,当流涉及终端的时候,通常使用的是行缓冲。
<3.3>无缓冲,无缓冲指的是标准IO库不对字符进行缓冲存储;注意,标准出错流stderr通常是无缓冲的。
printf是一个行缓冲函数,先写到缓冲区,满足条件后,才将缓冲区刷到对应文件中,刷缓冲区的条件如下:
(1)缓冲区填满;
(2)写入的字符中有‘\n’ ,'\r';
(3)调用fflush手动刷新缓冲区;
(4)调用scanf要从缓冲区中读取数据时,也会将缓冲区内的数据刷新;
满足上面4个条件之一缓冲区就会刷新
下面是代码实现:
看一下效果图:
2.知道了上面按一段一段显示的原因,下面我们就来改进一下它,通过fflush这个函数就可以解决这个问题。
fflush用于清空缓冲流,这样就会立刻输出所有在缓冲区的内容,也就能即时刷新,这样刚好就满足了进度条的实时性。
下面是效果展示:
3.上面基本达到了我们想要的效果,但是还是不好,在你下载文件的时候人家就有一个百分比来提示你下载了多少了,而我们这只有一个进度条,前进了多少还得自己估计,这样多不好啊,所以我们也来实现一下这种方式。
效果图:
4.上面实现的看似都有了该有的效果,但是我们还是会感觉有些欠缺,比如有时候进度条会有停止不前的时候,这个时候我们很难知道程序是在继续运行还是卡住了,下面我通过一种动态旋转的图标对其进行优化。
旋转图标自己可以定,“- \ \ | /”或“| / - \ \”都可以
效果图:
5.最后再提一点,我在运行代码时就用了两个命令,make 和./Proc,那是因为我提前就编写了一个Makefile文件,这样就方便了我们运行代码。
下面就来看一下Makefile文件:
作为一个好习惯,记得每次在执行完./Proc后make clean一下
相关文章推荐
- Linux中实现一个简单的进度条【转】
- 用linux实现一个简单的进度条
- linux中实现一个简单的进度条
- 【Linux】Linux下实现一个简单的进度条程序
- Linux下实现一个简单进度条和shell脚本实现彩色进度条
- Linux中实现一个简单的进度条
- Linux网络编程:一个简单的正向代理服务器的实现
- 在Linux下用C语言写一个小程序实现一个进度条编写Makefile来进行运行
- linux0.11学习笔记-技术铺垫-简单AB任务切换程序(1)-实现一个简单的bootloader
- 在Linux下基于tcp协议实现一个简单的通信
- LINUX实现简单的进度条
- 由最简单的一个例子说起,匿名用户可读可写的实现(LINUX)配置
- 用Ajax实现一个简单的进度条
- 用Linux编写程序,实现一个简易的进度条
- Linux下之使用简单3种创建文件的命令,并实现一个Html和JavaScript小程序
- linux——学习篇(三)之makefile的简单应用及实现简单的进度条
- linux之 从0构建一个简单的小linux详解(脚本实现)
- Linux C++ 一个线程池的简单实现(附代码)
- 利用linux下的c语言编程来简单的实现一个shell功能实现!
- 【1】实现一个简单的linux系统引导程序