默认情况下,stdout 行是缓冲的、无缓冲的还是不确定的?
Posted
技术标签:
【中文标题】默认情况下,stdout 行是缓冲的、无缓冲的还是不确定的?【英文标题】:Is stdout line buffered, unbuffered or indeterminate by default? 【发布时间】:2011-04-13 00:49:22 【问题描述】:c99
的 7.9.13/7
部分指出:
在程序启动时,三个文本流是预定义的,不需要显式打开 - 标准输入(用于读取常规输入)、标准输出(用于写入常规输出)和标准错误(用于写入诊断输出)。
最初打开时,标准错误流没有完全缓冲;当且仅当可以确定流不引用交互式设备时,标准输入和标准输出流才会被完全缓冲。
所以这是有道理的。如果您将标准输出推送到文件中,您希望它完全缓冲以提高效率。
但是当您无法确定设备是非交互式的(即正常输出到终端)时,我在标准中找不到关于输出是行缓冲还是非缓冲的提及.
我问的原因是对我的回答 here 的评论,我应该在两个语句之间插入一个 fflush(stdout);
:
printf ("Enter number> ");
// fflush (stdout); needed ?
if (fgets (buff, sizeof(buff), stdin) == NULL) ...
因为我没有用换行符终止 printf
。谁能解决这个问题?
【问题讨论】:
【参考方案1】: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
上读到了recent thread 关于同样的事情。备注之一:
Unix 约定是
stdin
和stdout
在与终端关联时是行缓冲的,否则是全缓冲的(也就是块缓冲的)。stderr
始终没有缓冲。
【讨论】:
您不能“暂时”使stdout
无缓冲。 setbuf
和 setvbuf
具有未定义的行为,除非它们是文件打开后对其执行的第一个操作。
在行缓冲的情况下,是否存在高水位线,如果行太长会被刷新?
@CMCDragonkai 默认行缓冲区大小是实现定义的,取决于它指向的内容(管道的缓冲区大小与终端或文件不同)。更多详情***.com/questions/10904067/…
“在 Linux 上,stdout 是行缓冲的”——仅当它是 TTY 时。以上是关于默认情况下,stdout 行是缓冲的、无缓冲的还是不确定的?的主要内容,如果未能解决你的问题,请参考以下文章