为什么带 \n 的 printf() 在 Windows 上仍然不刷新?

Why does printf() with \n still not flush on Windows?

我的 Windows 程序(使用 MSYS2 MINGW64 编译)以大块输出其 stdout 数据。使用 \nprintf() 调用未正确刷新输出。

作为 this question 的变体,在什么条件下 printf() 不冲洗?


例如,以下代码在 MSYS2 MINGW64 上按块输出:

#include <stdio.h>

int main() {
        while(1) {
                printf("test\n");
                Sleep(1);
        }
        return 0;
}

在 Windows 上没有行缓冲,只有无缓冲和全缓冲

  • _IOLBF
    • For some systems, this provides line buffering. However, for Win32, the behavior is the same as _IOFBF - Full Buffering.

setvbuf

稍等片刻,直到缓冲区已满,或自行刷新缓冲区。或者,您可以使用 setvbuf() 减小缓冲区大小,以便更频繁地刷新

作为对其他答案的补充,您可以在 printf 中完成所有输出,只是不要执行 \n 而是在其后使用 cout << endl。那应该刷新输出。

under what conditions does printf() NOT flush?

使用 mingw-w64,我不知道,但是 mingw-w64 的行为不需要在其他地方应用。谨慎编码仅针对一种实现。

以下一般适用于 C。

通常,如果 printf() 缺少 '\n',它不会刷新,但这是 实现定义的 行为。

printf() 刷新或不刷新的条件是实现定义的。有很多可能性。参见

为确保 stdout 已刷新 ,请在后面加上 fflush(stdout);

貌似在msys2 shell 运行ning under mintty下,至少对于MINGW64,'stdin', 'stdout' and 'stderr' all report 0 (false) 对于 'isatty()',而如果您打开 Windows CMD.EXE 提示和 运行 相同的可执行文件,所有三个文件描述符(0、1 和 2)return 1(真)。

我不相信这一直是行为,因为我很确定在我重新安装 msys2 之前我从来没有 运行 进入这个。

根据 POSIX,这不是正确的行为。1 [IEEE Std 1003.1-2017(IEEE Std 1003.1-2008 的修订版)],https://pubs.opengroup.org/onlinepubs/9699919799/

At program start-up, three streams shall be predefined and need not be opened explicitly: standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). When opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.

我的测试表明,当 运行在 mintty 中 bash shell 时,stdout 和 stdin 都没有 完全缓冲。

将以下内容添加到“main()”的开头确实会使 stderr 和 stdout 成为非缓冲的:

   (void)setvbuf(stdout, NULL, _IONBF, 0);
   (void)setvbuf(stderr, NULL, _IONBF, 0);