我知道这是因为缓冲了stdout但是我什么时候可以在下面的程序中期望输出stdout。如果我跑,我总是得到“stderr”作为输出。如果我添加'\ n'或fflush(标准输出),那么只有我得到两个语句。如果我不添加'\ n'或fflush(stdout),我没有得到“stdout”作为输出。如果我不添加'\ n'或fflush(stdout),我什么时候才能将所有缓冲的“stdout”作为输出。
#include <stdio.h>
#include <unistd.h>
int main()
{
for(;;)
{
fprintf(stdout,"stdout");
fprintf(stderr,"stderr");
sleep(1);
}
return 0;
}
答案 0 :(得分:4)
实际上,新行或者齐声因为默认stdout
在引用终端设备时是行缓冲的。
更确切地说:标准输入和标准输出是完全缓冲的,当且仅当它们不引用交互式设备时。标准错误永远不会完全缓冲。
关于线路缓冲,引自APUE:
线路缓冲有两个警告。首先,标准I / O库用于收集每一行的缓冲区大小是固定的,因此如果我们在写入换行符之前填充此缓冲区,则可能发生I / O.其次,无论何时通过标准I / O库从(a)无缓冲流或(b)行缓冲流(需要从内核请求数据)请求输入,都刷新所有行缓冲输出流。 (b)中限定符的原因是所请求的数据可能已经存在 在缓冲区中,不需要从内核读取数据。显然,来自无缓冲流(项目(a))的任何输入都需要从内核获取数据。
要将其更改为无缓冲,请使用setvbuf
:
setvbuf(stdout, NULL, _IONBF, 0);
答案 1 :(得分:0)
发送到stderr的输出通常会立即打印。这是标准错误输出。当然,错误应该立即显示,因此任何存在的缓冲区都会立即刷新。
另一方面,stdout是缓冲的。打印出来的缓冲区因语言而异,但通常至少需要以下两种方法之一:/n
或其他类型的换行符或.flush();
。如果您不提供这些选项,那么通常您必须等待缓冲区填充。这可能需要花费任何时间,因为它几乎完全取决于缓冲区的大小。
按照惯例,处理流的方式是您根据需要将尽可能多的信息推送到它们中,然后调用.flush()
。如果缓冲区恰好在此期间填满,那么数据将被发送到任何地方,缓冲区开始再次填满。
但是,这里填写了一个接收文本的缓冲区。与二进制信息相比,文本并没有真正占用大量空间(这是一个非常主观的陈述,应该松散地解释),因此填充缓冲区可能需要一段时间。
最佳做法是,在您将所有要打印的文本“送入”之后,手动清除流(stdout
)。
答案 2 :(得分:0)
fprintf 是行缓冲的。您可以通过调用 setvbuf 来改变行为。它允许您将其设置为“unbuffered”,“line buffered”或“full buffered”。