0

我的 Windows 程序(使用 MSYS2 MINGW64 编译)以大块的形式输出其stdout数据。带有 a的printf()调用\n无法正确刷新输出。

作为这个问题的一个变体,在什么情况下不printf()刷新?


例如,以下代码在 MSYS2 MINGW64 上以块的形式输出:

#include <stdio.h>

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

4 回答 4

3

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

  • _IOLBF
    • 对于某些系统,这提供了行缓冲。但是,对于 Win32,其行为与_IOFBF- Full Buffering 相同。

设置vbuf

等待一段时间,直到缓冲区已满,或者自己刷新缓冲区。或者,您可以减小缓冲区大小,setvbuf()以便更频繁地刷新

于 2020-04-26T01:58:24.273 回答
2

在什么条件下不printf()冲洗?

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

以下一般适用于 C。

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

printf()刷新或不刷新的条件由实现定义。有很多可能性。请参阅C 中自动标准输出缓冲区刷新的规则是什么

为确保stdout冲走,请使用fflush(stdout);.

于 2020-04-26T02:13:35.187 回答
1

似乎在 mintty 下运行的 msys2 shell 中,至少对于 MINGW64,“stdin”、“stdout”和“stderr”都为“isatty()”报告 0 (false),而如果你打开 Windows CMD.EXE 提示并运行相同的可执行文件,所有三个文件描述符(0、1 和 2)都返回 1(真)。

我不相信这一直是这种行为,因为我很确定在重新安装 msys2 之前我从未遇到过这种情况。

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

在程序启动时,应预定义三个流且无需显式打开:标准输入(用于读取常规输入)、标准输出(用于写入常规输出)和标准错误(用于写入诊断输出)。打开时,标准错误流没有完全缓冲;当且仅当可以确定流不引用交互式设备时,标准输入和标准输出流才会被完全缓冲。

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

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

   (void)setvbuf(stdout, NULL, _IONBF, 0);
   (void)setvbuf(stderr, NULL, _IONBF, 0);
于 2021-04-16T23:47:35.503 回答
-1

作为其他答案的补充,您可以在不做的情况下完成所有输出,printf而是\ncout << endl它之后使用。那应该刷新输出。

于 2020-04-26T02:03:16.563 回答