Linux进度条小程序(结合缓冲区相关知识)
Posted DR5200
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux进度条小程序(结合缓冲区相关知识)相关的知识,希望对你有一定的参考价值。
文章目录
一.行缓冲
#include<stdio.h>
#include<string.h>
#include<unistd.h>
int main()
printf("hello world!\\n");
sleep(5);
#include<stdio.h>
#include<string.h>
#include<unistd.h>
int main()
printf("hello world!");
sleep(5);
在写我们的进度条之前,先讲一些补充知识,首先我们来看下面这两段代码,可以发现两段代码唯一的区别就是printf末尾加没加 \\n ,可能很多同学认为这两段代码运行结果是一样的,但实际上运行之后我们可以看到第一段代码先打印出 hello world 再 sleep 5秒,第二段代码先 sleep 5 秒,再打印出 hello world
这是怎么回事呢? 莫非第二段代码 printf 和 sleep 的执行顺序变了? 当然不是,我们的代码肯定是从上到下依次执行的,printf 一定是先于 sleep 执行的, 真正的原因是 hello world 被缓存起来,并没有立即被刷新到显示器,当 sleep 5秒后,缓冲区的内容才被刷新出来,下面介绍一下缓冲区的分类
缓冲区的分类
全缓冲:我们缓存在缓冲区的东西在缓冲区满的时候,才写入磁盘或者我们调用fflush刷新缓冲区才能写入到磁盘。对于全缓冲,如果我们缓冲区没满,或者我们没有手动刷新缓存,那么缓存区的内容是不能写入到磁盘的。(对文件写入时采用全缓冲)
行缓冲:我们标准输入、标准输出都是采用的行缓存,也就是遇到换行符的时候,才会将缓存区的东西写入到磁盘。
无缓存:有的时候,我们希望一些内容在第一时间写入磁盘或者显示出来,比如我们显示错误信息的时候,这时候典型的例子比如标准出错,它就是直接显示出错信息,而不会先放入缓存。
通常情况下,我们需要知道的是,在缓冲区满、手动调用fflush、或者程序结束的时候,我们的缓冲区才会得到刷新,并写入磁盘。
由此,我们就可以知道原因了,hello world 按照行缓冲的方式缓存到缓冲区,遇到换行符才会被刷新到显示器上,所以第一段代码缓冲区里是 hello world\\n,遇到换行符被刷新出来,第二段代码缓冲区里是 hello world,没有遇到换行符,直到程序结束,缓冲区的内容才被刷新出来
(1). 这个缓冲区在哪里 ?
(2). 这个缓冲区是谁提供的?
(3). OS也是有缓冲的 vs 文件缓冲
#include<stdio.h>
#include<unistd.h>
int main()
printf("hello printf\\n");
fprintf(stdout,"hello fprintf\\n");
const char* buf = "hello write\\n";
write(1,buf,strlen(buf));
fork();
return 0;
这段代码我们 ./myproc 运行起来,结果如我们所想,但如果重定向到一个文件当中,结果就不如我们所想了
二.\\n和\\r
换到下一行 : 换行(\\n)
回到一行的开始 : 回车(\\r)
在C/C++中,\\n 表示的有两个意思 : 回车 + 换行
我们平常键盘上的Enter键就是回车 + 换行的功能,这也是为什么Enter键上的图标是一弯箭头,表示换到下一行并回到下一行的开始
结合以上的知识,我们可以先写出一个简易的倒计时程序
#include<stdio.h>
#include<string.h>
#include<unistd.h>
int main()
int i = 10;
while(i)
printf("%2d\\r",i);
// 刷新缓冲区
fflush(stdout);
sleep(1);
i--;
三.进度条实现
#include<stdio.h>
#include<string.h>
#include<unistd.h>
int main()
int i = 0;
char proc[102];
memset(proc,'\\0',sizeof proc);
const char* lable = "|/-\\\\";
while(i <= 100)
printf("[%-100s][%d%%][%c]\\r",proc,i,lable[i % 4]);
// 刷新缓冲区
fflush(stdout);
proc[i] = '#';
usleep(100000);
i++;
printf("\\n");
以上是关于Linux进度条小程序(结合缓冲区相关知识)的主要内容,如果未能解决你的问题,请参考以下文章