我正在编写一个 C 程序,我在其中打印到 stderr 并在代码中使用 putchar() 。我希望控制台上的输出显示所有标准错误,然后在程序结束之前最终刷新标准输出。有谁知道当 putchar('\n') 发生时会阻止标准输出刷新的方法?
我想我可以只做一个 if 语句来确保它不会放置任何换行符,但我更希望将一些代码行或几行代码放在程序的顶部以停止所有刷新,直到我说 fflush(stdout) 在程序底部
你试图做的事情非常脆弱。在任何情况下, C 都没有规定 stdio 的实现不刷新输出的义务。即使你让它为你工作,这种行为也取决于不超过缓冲区大小。如果您真的需要这种行为,您可能应该自己缓冲输出(可能将其写入 atmpfile()
而不是stdout
)然后将其全部复制到stdout
程序退出之前的最后一步。
使用管道从控制台运行您的命令:
my_command >output.txt
所有的输出stderr
都会立即出现。写的东西stdout
会去output.txt
。
您可以使用setvbuf()
完全缓冲输出stdout
并为您的目的提供足够大的缓冲区大小:
#include <stdio.h>
int main() {
// issue this call before any output
setvbuf(stdout, NULL, _IOFBF, 16384);
...
return 0;
}
输出到stderr
默认情况下是无缓冲的,因此它应该立即转到控制台。stdout
连接到终端时,输出到默认情况下是行缓冲的。将其设置为_IOFBF
(完全缓冲)应该可以防止putchar('\n')
刷新挂起的输出。
仅限窗户。如果有人有的话,我自己还在寻找 Unix 解决方案!
这是 Windows 的一个最小工作示例,它在不刷新的情况下将缓冲区发送到标准输出。您可以通过更改在刷新之前调整最大缓冲区大小max_buffer
,尽管我想有一些上限!
#include <windows.h>
#include <string.h>
int main()
{
const char* my_buffer = "hello, world!";
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
int max_buffer = 1000000;
int num_remaining = strlen(my_buffer);
while (num_remaining)
{
DWORD num_written = 0;
int buffer_size = num_remaining < max_buffer ? num_remaining : max_buffer;
int retval = WriteConsoleA(hStdout, my_buffer, buffer_size, &num_written, 0);
if (retval == 0 || num_written == 0)
{
// Handle error
}
num_remaining -= num_written;
if (num_remaining == 0)
{
break;
}
my_buffer += num_written;
}
}