25

部分声明7.9.13/7c99

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

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

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

但是当您无法确定设备是非交互式的(即,正常输出到终端)时,我在标准中没有提到输出是行缓冲的还是非缓冲的。

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

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

因为我没有printf用换行符终止。任何人都可以清除这个吗?

4

1 回答 1

35

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

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

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

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


另一种方法是使stdout无缓冲:

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

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


我刚刚阅读了关于同一件事的最新帖子。comp.lang.c备注之一:

Unix 约定是,当stdinstdout终端关联时,它是行缓冲的,否则是完全缓冲的(也就是块缓冲的)。stderr总是无缓冲的。

于 2010-09-19T17:52:34.637 回答