我的机器正在运行ubuntu 10.10,我正在使用标准的gnu C库 . 我的印象是,如果格式字符串中描述了换行符,printf会刷新缓冲区,但是下面的代码反复出现了这种趋势 . 有人可以澄清为什么缓冲区没有被刷新 .
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
int main()
{
int rc;
close(1);
close(2);
printf("HI 1\n");
fprintf(stderr, "ERROR\n");
open("newfile.txt", O_WRONLY | O_CREAT | O_TRUNC, 0600);
printf("WHAT?\n");
fprintf(stderr, "I SAID ERROR\n");
rc = fork();
if (rc == 0)
{
printf("SAY AGAIN?\n");
fprintf(stderr, "ERROR ERROR\n");
}
else
{
wait(NULL);
}
printf("BYE\n");
fprintf(stderr, "HI 2\n");
return 0;
}
运行该程序后newfile.txt的内容如下 .
HI 1
WHAT?
SAY AGAIN?
BYE
HI 1
WHAT?
BYE
3 回答
不,标准表示如果可以确定输出设备是非交互设备,那么
stdout
最初是完全缓冲的 .这意味着,如果您将
stdout
重定向到文件,它将不会在换行符上刷新 . 如果您想尝试强制它进行行缓冲,请使用setbuf
或setvbuf
.C99的相关部分,
7.19.3 Files, paragraph 7
,陈述:请记住
5.1.2.3/6
:如果输出设备是例如终端,则刷新它 .
如果输出设备可以确定为 non-interactive ,例如文件,则必须输出缓冲区 . 新行不会自动执行此操作 .
有关详细信息,请参阅paxdiablo's answer .
你有一种奇怪的幽默感 . :)
关闭用于stdout和stderr的文件描述符,然后立即尝试使用C stdout和stderr FILE流 . 不是一个好主意,我不确定C库会向你报告错误,但崩溃将是一种可接受的可能性 .
抛开这种奇怪的,当你重新写入终端时,通常的行为就是行缓冲 . 如果您正在写入管道,文件或套接字,那么通常的行为是块缓冲 . 您可以使用
setvbuf(3)
函数更改缓冲行为 . 有关缓冲行为的完整详细信息,请参见联机帮助页 .