为什么带 \n 的 printf() 在 Windows 上仍然不刷新?
Why does printf() with \n still not flush on Windows?
我的 Windows 程序(使用 MSYS2 MINGW64 编译)以大块输出其 stdout
数据。使用 \n
的 printf()
调用未正确刷新输出。
作为 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()
减小缓冲区大小,以便更频繁地刷新
作为对其他答案的补充,您可以在 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);
我的 Windows 程序(使用 MSYS2 MINGW64 编译)以大块输出其 stdout
数据。使用 \n
的 printf()
调用未正确刷新输出。
作为 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()
减小缓冲区大小,以便更频繁地刷新
作为对其他答案的补充,您可以在 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);