一、\r 和 \n
- \r :回车,光标回到该行的最开始。
- \n:换行,光标来到下一行的最开始。
二、行缓冲区
//(1)
#include <stdio.h>
#include <time.h>
int main()
{
printf("hello world!\n");
sleep(3);
return 0;
}
//(2)
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("hello world!");
sleep(3);
return 0;
}
运行上述两个代码,有什么区别?
第一个代码:直接打印hello world! 三秒后程序结束。
第二个代码:三秒后打印hello world! 同时程序结束。
为什么?
因为有缓冲区这个东西,程序运行时,你printf的字符会先存在缓冲区中,等到缓冲区刷新就打印在屏幕上,而\n起到了刷新缓冲区的作用。
我们来修改一下第二段代码:
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("hello world!");
fflush(stdout); //刷新缓冲区
sleep(3);
return 0;
}
这样就会先打印hello world,然后三秒后程序结束。
再来看看下面两段代码:
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("hello world!\r");
sleep(3);
return 0;
}
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("hello world!\r");
fflush(stdout);
sleep(3);
return 0;
}
第一段代码:什么都不显示,三秒后程序结束。
第二段代码:打印hello world,三秒后hello world消失被覆盖,程序结束。
因为\r使光标回到了行首,所以命令提示覆盖了hello world。
三、进度条
#include "proc.h"
#define SIZE 102
#define STYLE '='
#define ARR '>'
void process()
{
const char* label = "|/-\\"; //模拟加载圈
char a[SIZE];
memset(a, '\0', sizeof(a));
int i = 0;
while (i <= 100)
{
printf("[%-100s][%d%%][%c]\r", a, i, label[i % 4]); //-100是让‘=’靠左对齐,以实现从左向右加载。
fflush(stdout);
a[i++] = STYLE;
if (i != 100)
{
a[i] = ARR; //模拟箭头
}
usleep(100000); //单位为毫秒
}
printf("\n");
}