#include
#include
#include
int main()
{
printf("hello world!\n");
sleep(5);
}
#include
#include
#include
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
#include
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)
在C/C++中,\n 表示的有两个意思 : 回车 + 换行
我们平常键盘上的Enter键就是回车 + 换行的功能,这也是为什么Enter键上的图标是一弯箭头,表示换到下一行并回到下一行的开始
结合以上的知识,我们可以先写出一个简易的倒计时程序
#include
#include
#include
int main()
{
int i = 10;
while(i)
{
printf("%2d\r",i);
// 刷新缓冲区
fflush(stdout);
sleep(1);
i--;
}
}
#include
#include
#include
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");
}