默认情况下,stdout 行是缓冲的、无缓冲的还是不确定的?

Is stdout line buffered, unbuffered or indeterminate by default?

提问人:paxdiablo 提问时间:9/16/2010 最后编辑:ktbpaxdiablo 更新时间:9/5/2023 访问量:19221

问:

该节指出:7.19.3/7c99

在程序启动时,三个文本流是预定义的,不需要显式打开——标准输入(用于读取常规输入)、标准输出(用于写入常规输出)和标准错误(用于写入诊断输出)。

最初打开时,标准错误流未完全缓冲;当且仅当可以确定流不引用交互式设备时,标准输入和标准输出流才会完全缓冲。

所以这是有道理的。如果要将标准输出推送到文件,则希望它完全缓冲以提高效率。

但是,当您无法确定设备是非交互式的(即,正常输出到终端)时,我在标准中找不到关于输出是线路缓冲还是无缓冲的提及。

我问的原因是对我在这里的回答的评论,我应该在两个陈述之间插入一个:fflush(stdout);

printf ("Enter number> ");
// fflush (stdout); needed ?
if (fgets (buff, sizeof(buff), stdin) == NULL) { ... }

因为我没有用换行符终止。谁能解决这个问题?printf

标准输出 C99 缓冲

评论


答:

39赞 schot 9/20/2010 #1

C99 标准没有指定这三个标准流是无缓冲的还是行缓冲的:这取决于实现。我所知道的所有 UNIX 实现都有一行缓冲。在 Linux 上,是行缓冲和无缓冲。stdinstdoutstderr

据我所知,POSIX没有施加额外的限制。POSIX 的 fflush 页面在 EXAMPLES 部分确实注明:

[...]使用 fflush() 函数是因为标准输出通常是缓冲的,并且提示可能不会立即打印在输出或终端上。

所以你添加的评论是正确的。fflush(stdout);


另一种方法是使 unbuffered:stdout

setbuf(stdout, NULL);
/* or */
setvbuf(stdout, NULL, _IONBF, 0);

但正如 R. 所指出的,你只能这样做一次,而且必须在你写入或对它执行任何其他操作之前。(C99 7.19.5.5 2)stdout


我刚刚读了一篇关于同一件事的最新帖子。其中一句话:comp.lang.c

Unix 的约定是,当与终端关联时,并且是行缓冲的,否则是完全缓冲的(又名块缓冲)。 始终是无缓冲的。stdinstdoutstderr

评论

2赞 R.. GitHub STOP HELPING ICE 9/13/2011
你不能“暂时”使无缓冲。 并且具有未定义的行为,除非它们是文件打开后对文件执行的第一个操作。stdoutsetbufsetvbuf
0赞 CMCDragonkai 4/25/2016
在线路缓冲的情况下,是否有高水位线,如果线路太长,它将被冲洗?
0赞 Chuck Adams 1/26/2017
@CMCDragonkai 默认行缓冲区大小由实现定义,取决于它指向的内容(管道的缓冲区大小与终端或文件不同)。更多详情请见 stackoverflow.com/questions/10904067/...
6赞 Charles Duffy 3/23/2019
“在 Linux 上,stdout 是行缓冲的”——仅当它是 TTY 时。