缓冲区说明
C中的字符分为:
1.可显字符
2.控制字符
\r :回车—换行+回到行开头
\n:换行—换行
在Linux下写以下代码并创建makefile文件运行的结果分别是?
1.printf什么都不加
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("hello world!");
sleep(2);
return 0;
}
2.printf+\n
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("hello world!\n");
sleep(2);
return 0;
}
3.printf+\r
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("hello world!\r");
sleep(2);
return 0;
}
1.printf不加\n
现象1:
等待2秒以后,才打印hello world!
但是并不是先执行sleep再执行printf的,一定是从上往下执行。
在sleep期间,hello world!只是没有被刷新出来,被保存在了缓冲区,程序结束再刷新缓冲区打印。
2.printf加\n
现象2:
先打印hello world!,然后再等待两秒。
为什么加了\n以后数据就会先打印了呢?
不管加不加\n,数据都会先被保存在缓冲区中,此处缓冲区的缓冲策略:行缓冲
行缓冲——只要碰到了换行符,就会把包括换行符在内的之前的所有缓冲区内的内容刷新出来。(刷新策略还有很多,这只是其中一种)
所以碰到\n,先刷新依次缓冲区打印数据,然后等待两秒程序结束,再打印命令行。
3.printf加\r
现象3:
什么都不打印,仅等待2秒。
为什么加\r换行什么都不会打印呢?
因为换行是:换行+返回开头
\r会返回开头,在数据存储进入缓冲区以后,等待两秒,程序要结束,先打印hello world!,打印完成后遇到\r光标返回这一行的开头,然后还需要打印命令行,这时命令行会把hello world!给覆盖掉,(程序结束–>缓冲区的数据就被刷新–>缓冲区刷新字符串打印出来)而由于两次打印的速度太快,看起来的结果就和没输出printf一样。
补充:
这里在printf以后,用 fflush(stdout); 来刷新缓冲区先把hello world!打印出来,再sleep等待2秒结束程序,可以清晰的看见这个过程。
实现倒计时
通过前面缓冲区的知识来实现倒计时:
原理:不断刷新字符,并通过\r让光标回到开头覆盖数据打印实现倒计时。
#include<stdio.h>
#include<unistd.h>
int main()
{
int i = 10;
while(i, i >= 0, i--)
{
printf("%2d\r",i);//输出两位数,10以后要在第二位刷新数据,所以用%2d
fflush(stdout);//刷新缓冲区
sleep(1);
}
printf("\n");
return 0;
}
实现进度条
原理与实现倒计时类似:
#define SIZE 102 //进度条长度100 + 结尾\0 + 箭头1 = 102
#define STYLE '='
#define ARR '>'
void process()
{
char bar[SIZE];
const char* lab = "|/-\\";//旋转动画
memset(bar, '\0', sizeof(bar));//全部初始化为空字符
int i = 0;
while(i <= 100)
{
printf("[%-100s][%d%%][%c]\r", bar, i, lab[i%4]);
fflush(stdout);//刷新缓冲区,打印一下
bar[i++] = STYLE;
if(i != 100)
{
bar[i] = ARR;
}
usleep(100000);//刷新一次
}
printf("\n");
}
实现效果: