为什么这个c程序不打印第一个printf语句?

时间:2011-11-09 06:06:36

标签: c printf

#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。为什么会这样?有人可以解释其背后的原因吗?

3 个答案:

答案 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

的手册页