模拟进度条
来源:互联网 发布:linux 修改ip命令 编辑:程序博客网 时间:2024/06/05 14:56
本文通过编写模拟进度条程序来记录一些知识点,进度条始终在同一行显示,且不断的增加打印*个数以表示进度增加,程序如下:
1 #include <stdio.h> 2 3 void display_progress(int num) 4 { 5 int i = 0; 6 7 for (i = 0; i < num; i++) 8 { 9 printf("*"); 10 } 11 12 return; 13 } 14 15 16 int main(void) 17 { 18 int i = 0; 19 20 for (i = 0; i <= 100; i++) 21 { 22 printf("\r"); 23 display_progress(i); 24 fflush(stdout); 25 sleep(1); 26 } 27 28 printf("\n"); 29 30 return 0; 31 }
1、回车和换行 \r\n
'\r'回车符的意思是将光标移动到当前行的开始
'\n'换行符的意思则是将光标移动到下一行
在windows系统中是通过 "\r\n"实现换行操作
在linux系统中是通过"\n"实现换行操作
2、缓冲与缓存
一直没搞明白,缓冲和缓存是否可以混着用,我自己理解是缓冲是一种操作,用于该种操作的地方叫缓存,即缓冲区等于缓存。
(1)全缓冲 缓冲区填满才进行实际的I/O操作
(2)行缓冲 遇到换行符时才进行实际的I/O操作,如缓冲区满了,即便没遇到换行符也进行I/O操作
(3)无缓冲
3、printf函数
printf是一个行缓冲函数,先写到缓冲区,满足条件后,才将缓冲区刷到对应文件中,刷新缓冲区的条件如下:
1 缓冲区填满 (printf行缓冲区大小为1024字节)
2 遇到'\n' 或 '\r' 字符
3 调用fflush手动刷新缓冲区
4 调用scanf从缓冲区中读取数据
满足上面4个条件之一缓冲区就会刷新, 将数据写入到对应的文件
当我们执行printf的进程或者线程结束的时候会主动调用fflush来刷新缓冲区,所以程序结束,也会刷新
有时候会遇到该有的打印没有显示,就注意下是不是printf没有添加'\n'符号。
对与本程序而言,进度条需一直在同一行显示,固不能有'\n'进行换行操作,数据需通过fflush手动刷新到标准输出。
4、文件的写同步sync
让我想起另一个问题,记得有次往sd卡写数据,显示write接口已返回成功,我便拔掉了SD卡,结果查看数据并没有写完全。
这里存在的问题是在UNIX系统中,write函数是把数据从进程缓冲区拷贝到内核缓冲区当中便返回了,当缓冲区满或者内核要重用该缓冲区时,才把该缓冲区的数据排入输出队列,然后等到其到达队首时,才进行实际的I/O操作。即实际的写磁盘操作则可能在以后的某个时刻进行。这被称为延迟写,这样做的目的是减少系统调用,提高CPU的工作效率。如要及时同步磁盘文件,则可通过sync、fsync和fdatasync三个函数实现。
void sync(void);
sync函数只是将内核缓冲区的数据排入到输出队列就返回了,并没有进行实际的I/O操作。系统守护进程一般每隔一段时间就会调用该函数。
int fsync(int fd);
fsync与sync不同之处在于它等待写磁盘操作结束才返回,保证数据已同步到磁盘文件。
int fdatasync(int fd);
类似与fsync,不同之处在于只保存文件数据同步,不包括文件本身的特征数据。
5、fflush与fsync的关系
如通过fwrite库函数将数据写到文件当中,数据只是先写到了流缓冲区当中,可通过fflush只刷新位于流缓冲区中的数据,将其写到内核缓冲区当中,并不保证及时写到磁盘文件当中。固要及时同步还需调用fsync库函数实现。
存在问题
上述程序在运行过程中,如缩小屏幕宽度,那么在运行一段时间后,当屏幕宽度装不下一行打印的时候,自动分成了两行打印,而下一次的 “\r”操作只是回到了分2行后的第二行开头,这时变出现非预期的打印了,这种情况我还不知道怎么处理,如有清楚的,麻烦跟我讲解下,谢谢。
参考资料
http://www.ruanyifeng.com/blog/2006/04/post_213.html (讲述回车换行的来历,建议看下评论)
http://www.2cto.com/os/201409/339460.html (同步内核缓冲区讲解)
《UNIX环境高级编程》
0 0
- 模拟进度条
- 模拟进度条
- js模拟进度条
- dos模拟进度条显示
- JS模拟进度条
- Ajax模拟进度条
- C# 进度条模拟
- css+div模拟进度条
- AsyncTask模拟进度条
- 利用AsyncTask模拟进度条
- 模拟实现进度条
- 进度条的模拟实现
- linux进度条功能模拟
- JavaScript模拟实现进度条
- Ajax模拟制作进度条
- 模拟windows control的进度条
- js模拟文件上传进度条
- VBA窗体模拟显示进度条
- CCF(四)1-图像旋转
- 第二周 项目3-体验复杂度(1)
- vim快速选中、删除、复制、修改引号或括号内的内容
- volatile关键字解析
- java中volatile相关
- 模拟进度条
- 代码修改约束
- HUE3.9 Tarball安装
- 文件下载 FileInputStream不能读取中文路径的问题
- 在sublime运行php
- window与document的区别
- 关于Java中 Class.forName();
- Spring揭秘读书笔记 八 数据访问异常体系
- xtraBackup备份原理剖析(转)