#include<stdio.h>
#include <unistd.h>
int main(){
while(1)
{
fprintf(stdout,"hello-out");
fprintf(stderr,"hello-err");
sleep(1);
}
return 0;
}
在gcc中编译这个程序并执行它只会打印hello-err而不是hello-out。为什么会这样?有人可以解释其背后的原因吗?
答案 0 :(得分:17)
如果您在邮件中添加'\n'
,它将(或应该),即。 "hello-out\n"
。
原因是stdout
缓冲以提高效率,而stderr
不缓冲它的输出,更适合于错误消息和事物需要立即打印。
编辑:我想在计算机崩溃之前添加的另一件事......两次......你还可以使用stdout
\n
)stdin
fflush()
被调用setbuf(stdout, NULL);
来禁用stdout
的缓冲。在我不得不使用write()
(Unix)并且不希望我的输出被缓冲之前,我已经这样做了。
答案 1 :(得分:3)
它总是将输出打印到stdout,因为设计stdout是BUFFERED输出,而stderr是无缓冲的。通常,对于缓冲输出流,直到系统“自由”执行此操作才会转储流。因此,在刷新之前,数据可以持续缓冲很长一段时间。如果要强制缓冲区刷新,可以使用fflush
#include<stdio.h>
#include <unistd.h>
int main(){
while(1)
{
fprintf(stdout,"hello-out");
fflush(stdout); /* force flush */
fprintf(stderr,"hello-err");
sleep(1);
}
return 0;
}
更新: stdout 在连接到终端时是线路缓冲的,否则只是缓冲(例如重定向或管道)
答案 2 :(得分:1)
您忘记了字符串中的换行符(标记为\n
)。或者您需要在fflush(NULL);
fflush(stdout);
或至少sleep(1);
fprintf(stdout, ...)
与printf(...)
您需要输出换行符或调用fflush
,因为(至少在Linux上)stdout
FILE缓冲区是行缓冲的。这意味着C库正在缓冲数据,并且当缓冲区足够满时,或者当您使用新行或者通过新行刷新它时,将真正输出它(使用write
Linux system call)致电fflush
。需要缓冲,因为系统调用成本很高(对于要输出的每个字节,调用write
实际上太慢)。另请阅读setbuf