关于printf()函数不输出的问题
--发布于 2023-05-30 08:18:01
首先,看一个问题
#include <stdio.h>
#include <unistd.h> // sleep()函数的头文件
int main() {
printf("hello world");
sleep(5);
return 0;
}
问题:对于上面的程序代码,hello world
会在什么输出?
- A. 会立刻输出
- B. 在5秒后输出
答案是:B,hello world
会在5秒后程序结束时才输出。
那为什么是5秒后才输出呢?那是因为我们使用的printf函数属于标准I/O库的函数,标准I/O库是带有缓冲功能的,目的是尽量减少read()
和write()
系统调用的次数,提高性能。因为执行一次系统调用的性能消耗是比较高的。所以,标准I/O库的缓冲功能就是将这此输出攒起来,等积攒到一定程序后才真正地输出。
标准I/O提供了三种类型的缓冲:
- 全缓冲。这种缓冲区是输出到磁盘文件时才使用,它会等到缓冲区满了,才会进行真正的输出。
- 行缓冲。这种缓冲区的输出目的一般是屏幕终端,它一旦遇到了换行符后,就会进行真正的输出。这里我们可以注意到,上面的
hello world
后面是没有换行 符的,所以它会先攒起来。 - 不缓冲。标准出错流
stderr
就是不带缓冲的。一旦有什么错误信息,就立刻显示出来。
所以,可以总结一下:
- 标准出错stderr是不带缓冲的。
- 若是涉及终端设备(交互式设备),则它们是行缓冲的,否则是全缓冲的。
那么,如果我想立即输出怎么办?有3种方法。
方案1
既然输出到屏幕终端是行缓冲,那就将hello world
后面加上换行符,即
printf("hello world\n");
方案2
使用setbuf()函数,关闭缓冲机制。此时代码变为
#include <stdio.h>
#include <unistd.h>
int main() {
setbuf(stdout, NULL); // 关闭标准输出stdout的缓冲机制
printf("hello world");
sleep(5);
return 0;
}
方案3
使用fflush()函数强制输出缓冲区的内容。此时代码为
#include <stdio.h>
#include <unistd.h>
int main() {
printf("hello world");
fflush(stdout); // 强制输出stdout的缓冲区的内容
sleep(5);
return 0;
}
--更新于 2023-06-08 09:31:58