2009-08-07 76 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()函數。

希望幫助....

相關問題