\r 和 \n 的区别
- \r 表示回车 (回车表示换到当前行的最开始)
- \n 表示换行(换行只是换到下一行)
- 注意:但是在实际使用时,\n 就直接表示了 \r\n 回车换行。
缓冲区的概念
-
行缓冲:常见的是对显示器进行刷新数据时
- 即必须缓冲区中一行填满了或者遇到 \n 才会输出到显示器
-
全缓冲:对文件进行写入时采用全缓冲
- 即将整个缓冲区填满才会刷新到磁盘中。
- 无缓冲:即刷新数据时没有缓冲区。
行缓冲示例一:
-
下列代码执行后的结果是:停止5秒后才显示 hello world
- printf 这行代码是先执行的
- 但是 printf 中没有 \n ,并且缓冲区中的一行并没有填满,所以没有输出到显示器
- 所以继续执行下面的 sleep 代码
- 在程序结束后会刷新缓冲区,将缓冲区的内容输出到显示器,所以最后仍然会显示。
void test()
{
printf("hello world"); //加入 \n 后就会立即输出到显示器了。
sleep(5);
}
行缓冲示例二
- 下列代码显示结果为:倒计时,并且下一次的数字会覆盖上一次的数字。
- 因为 \r 只是回车,并未换行,所以依然会在之前那一行继续输出
- 并且回车后,会回到这一行的起始位置,所以覆盖了上一次的值。
#include <unistd.h>
void test()
{
int i = 10;
while(i)
{
printf("%2d\r",i); //%2d 表示显示两个字符
fflush(stdout); //fflush是一个库函数,用来立即刷新缓冲区输出到显示器中
sleep(1);
i--;
}
}
全缓冲与无缓冲示例一
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
//C语言函数
printf("hello printf\n");
fprintf(stdout,"hello fprintf\n");
//系统函数
const char * msg = "hello write\n";
write(1,msg,strlen(msg));
fork();
return 0;
}
- 正常输出到显示器中时,是正常显示三行
- 但是重定向输出到文件中时,会多打印2行
- 当往显示器中打印时,系统采用的是行缓冲,即运行到 printf 等函数后,立马将数据刷新到显示器。
- 但是当重定向打印到文件时,缓冲方式发生变化,变成全缓冲,全缓冲会等到程序结束时,一次性将缓冲区内容打印到文件中
- 程序最后创建了子进程,子进程会继承父进程的缓冲区(子进程的缓冲区和父进程缓冲区内容相同,但是不是一个缓冲区,进程的独立性,发生写实拷贝)
- 所以父进程刷新一次缓冲区后,子进程也会刷新缓冲区,所以会打印两次 C 函数的内容。
- 因为系统函数(系统接口)没有缓冲区,所以 write函数只打印一次,并且是第一个被打印。
缓冲区位置
- 缓冲区是由 C 语言本身自带的,所有的 C 函数接口都有缓冲区,而系统接口没有缓冲区。
- 缓冲区是维护在文件结构体 files_struct 中,files_struct 提供文件描述符和用户缓冲区。
相关文章
暂无评论...