write()到stdout和printf输出没有交错?

时间:2009-08-07 05:05:06

标签: c printf stdout

#include <stdio.h>
#define MAXLEN 256

int main() {
  int n;
  char buf[MAXLEN];
  while((n = read(0,buf,sizeof(buf))) != 0){
    printf("n: %d:",n);
    write(1,buf,n);
  }
  return 1;
}

程序的输出(用户输入第一个read和第一个write并由终端回显):

read
read
write
write
n: 5:n: 6:

在标准输入处按Ctrl + D后,printf的输出出现,而不是随后的读取。为什么会这样?

5 个答案:

答案 0 :(得分:20)

Printf已缓冲。

您可以使用fflush调用强制printf“刷新”其缓冲区:

#include <stdio.h>
#define MAXLEN 256

int main() {
  int n;
  char buf[MAXLEN];
  while((n = read(0,buf,sizeof(buf))) != 0){
    printf("n: %d:",n);
    fflush(stdout); /* force it to go out */
    write(1,buf,n);
  }
  return 1;
}

一般来说,printf()被缓冲是一件好事。无缓冲输出,尤其是需要屏幕更新等的可见控制台,速度很慢。足够慢以至于可以直接减慢打印很多的应用程序(特别是在Windows平台上; Linux和unix通常受影响较小)。

但是,如果printf() - fprintf(stderr,)故意无缓冲,则stderr被缓冲会让你感到困惑。因此,您可能会收到包含printf()个邮件的邮件。如果您写入另一个与终端关联的FILE句柄,并且可能没有缓冲,请确保首先明确fflush(stdout)

答案 1 :(得分:2)

fgets的联机帮助页告诉我:

       不建议将调用混合到stdio中的输入函数        具有低级调用的库,用于读取文件描述符关联(2)        与输入流一起使用;结果将是不确定的        可能不是你想要的。

因此,最好的解决方案是不要在同一个描述符上使用write和printf。

答案 2 :(得分:1)

Printf正在使用stdio并且它是缓冲的。 通过发送更改为“n:%d:\ n”

将其推出

答案 3 :(得分:1)

您可以使用std fflush()函数来刷新标准输出缓冲区,或者您可以在printf内的控制字符串末尾使用额外的\ n。像这样的东西

printf("\n :%d:\n",n);

最好使用write()&amp; read()函数用C代替printf()和scanf()。 printf和scanf遇到了一些问题,比如printf将字符串参数存储在stdout缓冲区中。因此需要手动冲洗,这通过fflush功能或通过\ n进行。在一个小的hello world打印程序中,你不会发现这样的问题,因为stdout缓冲区在程序执行结束时被刷新。更好的使用write()工作正常。 scanf也有读取空间的问题以及与stdin缓冲区相关的许多其他问题。

例如,在下面的代码中:

main()  {   char a; int i=0,c; for(;i<2;i++) { scanf("%d",&c); scanf("%c",&a);} }

上面的程序在按下回车时读到了进入标准输入的问题。我们可以解决这个问题,但不能刷新stdin缓冲区或使用\ n字符。总是更好地使用read()和write()函数。

希望有所帮助....

答案 4 :(得分:0)

使用fwrite(流版本)而不是写。

请注意,虽然与文件编号1相关联,但它不是一回事。