2009-08-07 79 views
6
#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由用户键入和呼应由终端)的输出是:写()到标准输出和printf输出不交错?

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

的printf的输出来按下Ctrl + d在后标准输入,而不是随后的读取。为什么会发生?

回答

18

printf被缓冲。

您可以强制的printf使用fflush调用“冲洗”它的缓冲区:

#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()被缓冲是一件好事。无缓冲输出,特别是需要屏幕更新等的可见控制台,速度很慢。速度慢到可以直接减慢printf'的应用程序的速度(特别是在Windows平台上; Linux和unix通常受影响较小)。

但是,printf()缓存确实咬你,如果你也fprintf(stderr,) - stderr故意不缓冲。因此,您可能会丢失一些printf()的消息;如果您写入另一个FILE句柄,该句柄也与终端相关联,并且可能无缓冲,请确保您首先明确fflush(stdout)

+5

您也可以在执行任何IO之前使用setvbuf()更改缓冲模式。 – AProgrammer 2009-08-07 06:51:08

+0

“'printf()'是[buffered](http://en.wikipedia.org/wiki/Data_buffer)”是什么意思? – ma11hew28 2014-04-26 17:12:09

+0

http://stackoverflow.com/a/17552608/242933 – ma11hew28 2014-04-26 17:50:10

1

printf正在使用stdio并被缓冲。 通过发送更改为“n:%d:\ n”将其推出。

+0

如果不是这样,或者不混合输出通道 - 即使用同一个功能,输出的所有内容。 – 2009-08-07 05:26:12

+1

\ n不保证刷新它。 – EFraim 2009-08-07 05:34:05

+1

stdout是行缓冲的,除非它指向非交互式设备。 – AProgrammer 2009-08-07 06:53:17

2

用于与fgets的手册页告诉我:

这是不可取的输入函数的调用,从标准输入输出 库低水平混合调用,读取(2)文件描述符associ- 与ated输入流;结果将是不确定的,并且很可能不是你想要的。

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

+0

POSIX非常小心地指定结果未定义的时间,以及基于“活动句柄”的抽象概念定义好的结果。请参阅http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_05_01 – 2011-01-08 17:23:05

0

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

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

1

您可以使用std fflush()函数来刷新标准输出缓冲区,也可以在printf中的控制字符串的末尾使用额外的\ n。事情是这样的

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

它总是更好地使用write()用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);} } 

作为得到的读数\问题N转换的stdin上按压输入上述程序。我们可以解决这个问题,但不能刷新标准输入缓冲区或使用\ n字符。最好使用read()和write()函数。

希望帮助....

相关问题