2011-11-09 72 views
6
#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。爲什麼會這樣?有人可以解釋它背後的原因嗎?爲什麼這個c程序不打印第一個printf語句?

+0

你的平臺是什麼? –

+0

你在哪裏看過你的印刷文字?首先'printf'打印到'stdout',然後打印到'stderr'。在你的情況下,可能是不同的輸出流 – Nekto

+0

@ JimBuck - 我正在使用Fedora Linux。 – bornfree

回答

17

如果您將一個'\n'添加到您的消息它將(或應該),即。 "hello-out\n"

其原因是在於stdout爲了更有效緩衝,而stderr不緩衝它的輸出並且是更合適的錯誤消息,並且需要立即印刷的東西。

stdout通常沖洗時:

  • 的換行(\n)是要被打印
  • 您從stdin
  • fflush()讀取在上調用它

編輯:我想在我的電腦崩潰之前添加的另一件事...兩次...是,您還可以使用setbuf(stdout, NULL);禁用緩衝stdout。我之前做過這個,當時我不得不使用write()(Unix),並且不希望我的輸出被緩衝。

+0

setbuf +1(stdout,NULL) –

+1

感謝您的解釋! – bornfree

+0

@bornfree:不用擔心,希望我解釋一下。 – AusCBloke

1

您在字符串中忘記了換行符(標註爲\n)。或者你需要調用fflush(NULL);或至少fflush(stdout);sleep(1);

而且fprintf(stdout, ...)相同printf(...)

你需要輸出換行或致電fflush,因爲(至少在Linux上)的stdout文件緩衝區是線 - 緩衝的。這意味着C庫正在緩衝數據,並且在緩衝區足夠大時,或者在用新線路刷新它時,或者通過調用fflush,將真正輸出它(使用write Linux system call)。緩衝是必要的,因爲系統調用是昂貴的(對於要輸出的每個字節,調用write實際上太慢)。另請參閱setbuf的手冊頁

+1

您能否詳細說明爲什麼需要?我想了解背後的原因。 – bornfree

+0

AusCBloke的回答解釋了它。 –

+0

正如其他人所回答的,因爲它被緩衝以減少I/O操作。調用fflush()會強制緩衝區被刷新。 – LeleDumbo

3

它不是總是將輸出打印到標準輸出,因爲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; 
} 

更新:標準輸出當連接到一個終端,並且簡單地緩衝,否則(例如,重定向或管)

被linebuffered
+0

謝謝!我明白了。 – bornfree

相關問題