在C中自动刷新stdout缓冲区的规则是什么?

And*_*iad 8 c buffer stdio

我只是好奇应该满足哪些条件自动刷新stdout缓冲区.

首先,我很困惑这个伪代码不会在每次迭代时打印输出:

while (1) {
    printf("Any text");
    sleep(1);
}
Run Code Online (Sandbox Code Playgroud)

但如果我添加换行符,它会.

经过几次实验,我发现在我的机器上stdout缓冲区被刷新:

  1. 当我输入1025个字符或更多字符时;
  2. 当我读到标准时;
  3. 当我将换行符添加到stdout时;

第一个条件是完全清楚的 - 当缓冲区已满时,应该刷新它.第二个也是合理的.但为什么换行符导致潮红?其他隐含的条件是什么?

chu*_*ica 9

自动刷新stdout缓冲区的规则是实现定义的(ID).当流是无缓冲,完全缓冲行缓冲时,它是ID .

当流未缓冲时,字符应尽快从源或目的地出现.否则,可以将字符作为块累积并发送到主机环境或从主机环境发送.

当流被完全缓冲时,当填充缓冲区时,字符将作为块传输到主机环境或从主机环境传输.

当流被行缓冲时,当遇到换行符时,字符将作为块传输到主机环境或从主机环境传输.此外,当填充缓冲区,在无缓冲流上请求输入时,或者在需要从主机环境传输字符的行缓冲流上请求输入时,字符旨在作为块传输到主机环境. .

对这些特性的支持是实现定义的,...C11dr§7.21.33


我只是好奇应该满足哪些条件自动刷新stdout缓冲区.

如果代码想确保输出肯定是刷新的,请使用fflush().可以自动刷新流的其他条件是实现定义的.


R..*_*R.. 6

  • 每当输出换行符时,应刷新行缓冲的输出流。

  • 每当尝试从任何行缓冲输入流进行读取时,实现都可以(但不要求)刷新所有行缓冲输出流。

  • 默认情况下不允许实现完全缓冲流,除非可以确定它们不与“交互式设备”关联。因此,当 stdin/stdout 是终端时,它们不能完全缓冲,只能行缓冲(或无缓冲)。

如果仅在输出到终端时需要刷新,则可以假设写入换行符会导致刷新。否则,您应该fflush在需要刷新的地方显式调用。

  • @chux:7.21.3 文件¶7:“当且仅当可以确定流不引用交互式设备时,标准输入和标准输出流才被完全缓冲。” 7.21.5.3 fopen 函数¶8:“当打开时,当且仅当可以确定流不引用交互设备时,流才被完全缓冲。” (2认同)

Nov*_*zen 6

请参阅的手册页setbuf(3)。默认情况下,stdout设置为行缓冲模式。

printf()及其变体使用缓冲输出,并委托给write(). 因此,该缓冲由 的 C 库实现控制printf,缓冲区和缓冲区设置位于FILE结构体中。

还值得注意的是 unix 手册页第 3 节和第 2 节之间的区别。第 2 部分由函数调用组成,这些函数调用直接与操作系统对话,并执行纯用户程序无法执行的操作。第 3 部分由用户可以自己重现的函数调用组成,这些函数调用通常委托给第 2 部分调用。第 2 部分函数包含允许 C 程序与外界交互并执行 I/O 的低级“魔法”。第 3 节函数可以为第 2 节函数提供更方便的接口。

printfscanfgetcharfputs和其他FILE *函数都是第 3 节函数,它们委托给write()read(),而 和 是第 2 节函数。read()并且write()不缓冲。 printf()与结构中的缓冲区交互FILE,有时决定通过 发送该缓冲区的内容write()