前置知识点
\n\r
\n
换行,但只是垂直向下,并不水平移动。
\r
回车,返回当前行的头部。
光标返回头部后再打印,会从头开始覆盖之前打印在该行的内容。
printf的\n默认解释成换行+回车。
光标是与显示器匹配的,光标在哪里,显示器上的打印就从哪里开始。
\r\n本质上是用于控制光标的位置。
所有printf向显示器打印的内容,都是字符。
缓冲区
例1:
#include<stdio,h>
int main(){
printf("hello world\n");
sleep(1);
return 0;
}
例2:
#include<stdio,h>
int main(){
printf("hello world");
sleep(1);
return 0;
}
例1字符串后跟了 ’ \n ’ ,编译运行,文本会被直接打印出来;
例2字符串后没跟 ’ \n ',编译运行,文本会等待1秒再被打印出来。
1.程序执行默认按顺序结构执行(无判断、循环的情况下),所以printf一定先于sleep执行,但是先执行不代表内容会先显示,printf的确执行了但是没有显示出来,然后执行了sleep休眠。当sleep结束,程序退出时,文本才被刷新出来。
2.执行sleep休眠的时候 ,printf已经执行完打印了,要打印的数据存放在缓冲区。当sleep执行完,程序退出时,缓冲区的数据才被刷新,打印到终端上。
3.’ \n '是行缓冲,行缓冲策略会在遇到换行符时刷新,进而打印。
4.在没有 ’ \n '的情况下刷新——fflush(stdout) 刷新标准输出流。
缓冲区中的内容只有在刷新时才会打印在屏幕上。
代码与运行效果
proc.h
#pragma once
#include <stdio.h>
extern void process();
main.c
#include "proc.h"
int main(){
process();
return 0;
}
proc.c
#include "proc.h"
#include <string.h>
#include <unistd.h>
#define SIZE 102//确保容纳>和\n
#define STYLE '#'
#define ARR '>'
void process(){
const char *lable = "-+x*";
char bar[SIZE];
memset(bar,'\0',sizeof(bar));//将bar的元素全部初始化为\0
int i=0;
while(i<=100){//0%-100%一共循环101次
printf("[\033[43;32;32m%-100s\033[0m][%d%%][%c]\r",bar,i,lable[i%4]);//预留100个字符的位置,负号是从左向右(默认是右对齐)。%%比\%更通用。
fflush(stdout);
bar[i++]=STYLE;//第101个#不会被打印出来,因为循环条件不再满足
if(i!=100){
bar[i]=ARR;
}
usleep(100000);//usleep单位为微秒
}
printf("\n");
}
运行效果