printf不刷新stdout能否输出到终端?重定向后文件为空原因探究
测试代码
#include <stdio.h> int main(){ char a[2] = {0}; a[0] = 't'; printf("%s", a); scanf("%c", a); return 0; }
底层逻辑说明
这个行为差异完全来自C标准库对stdout的默认缓冲策略区分,核心规则如下:
- 当stdout关联**交互式终端(TTY设备)**时,默认使用行缓冲模式,该模式下有一条专属刷新规则:调用任何从终端输入流读取数据的输入函数(比如
scanf、fgetc等)前,会自动刷新所有未写完的行缓冲输出流。你直接执行a.out时就是这个场景,所以scanf执行前已经把缓冲区里的t刷到了终端,你能直接看到输出。 - 当stdout关联普通磁盘文件时(也就是你用
> out.txt重定向的场景),默认切换为全缓冲模式,该模式下没有「输入函数调用前自动刷新」的规则,仅在三种情况下才会把缓冲区内容写入文件:缓冲区被写满(默认通常为4KB)、手动调用fflush(stdout)、程序正常退出。你输出的t只有1字节远没填满缓冲区,又用^C强制终止了进程,程序不会执行正常退出前的缓冲区冲刷逻辑,缓冲区里的内容直接随着进程被销毁,所以out.txt是空的。
疑问解答
- 为什么重定向后
out.txt是空的?
你提到的scanf触发stdout刷新的规则仅适用于终端场景的行缓冲模式,重定向到文件的全缓冲模式下该规则不生效,输出内容一直停留在用户态的标准IO缓冲区,没有写入磁盘,进程被强制终止后缓冲区内容直接丢失。 - 为什么直接运行时屏幕能显示
t?
终端场景下stdout为行缓冲,输入函数调用前自动刷新输出缓冲区的规则生效,scanf执行前已经把t输出到终端,所以可以正常看到内容。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

