2014-12-31 22 views
3

它必須非常簡單,但我無法捕捉它。使用T連續輸出的C程序

這是一個簡單的C程序寫入到標準輸出:

[email protected]:~/tst# cat tst.c 
#include <stdio.h> 
#include <unistd.h> 

int 
main(int argc, char **argv) 
{ 
     for (; ;) { 
       printf("Hello world!\n"); 
       sleep(1); 
     } 
     return 0; 
} 

現在,如果我想寫輸出到我的屏幕和一個文件:

[email protected]:~/tst# ./tst |tee file 

它只是不工作,我有空的屏幕和空文件​​。

如果我做了一個退出的程序,那麼它完美的工作,例如,

[email protected]:~/tst# ls |tee file 
Makefile 
file 
qq 
tst 
tst.c 
tst.o 
[email protected]:~/tst# cat file 
Makefile 
file 
qq 
tst 
tst.c 
tst.o 
[email protected]:~/tst# 

這是一種緩衝問題嗎?有人可以幫我做一個繼續節目的開球嗎?

+5

如果你嘗試'fflush(stdout);'? – fredtantini

+1

@fredtantini:那確實有用。真的很簡單。謝謝 - 隨時發佈它作爲答案。 – wick

+1

似乎有一些有用的答案[這裏](http://stackoverflow.com/questions/11337041/force-line-buffering-of-stdout-when-piping-to-tee)。 (我現在不在Linux機器上,所以我不能試用它。) –

回答

1

標準輸出流行緩衝如果流可以被確定爲是指一個交互設備(例如終端),否則它的全緩衝,因此,存在其中printf不沖水的情況下,即使它有一個換行符可用於打印,如管道輸出或重定向輸出;

> tst | tee file 
> tst > file 

調用printf()fflush(stdout)將解決這個問題。

C99相關正文部分7.19.3表示:

當一個數據流沒有緩衝時,字符將盡快從 來源或目的地出現。否則, 字符可能被累積並作爲一個塊傳輸到主機或從主機 環境中傳輸。

當一個流被完全緩衝時,當填充緩衝區 時,字符將打算作爲一個塊向/從主機環境發送或從主機環境發送。

當一個流被行緩衝時,當遇到一個換行符 字符時,字符被設置爲 作爲一個塊傳送到主機環境或從主機環境傳出。

最初打開時,標準錯誤流沒有完全緩衝; 如果 和只有當流可以確定不參考 交互式設備時,標準輸入和標準輸出流完全緩衝。

+0

您的回答似乎與您的報價相抵觸。 (**行緩衝**在答覆的第一句中,**完全緩衝**在報價的最後一句) – ace

+1

@ace,你是絕對正確的,我修正了它。非常感謝! – Alper

0

看來你的問題是stdout被緩衝,並且不會在新行後面顯示。您可以強制你的printf語句之後沖洗它來顯示它:

fflush(stdout); 

或者,你可以禁用緩衝:

setbuf(stdout, NULL); 

另外,請注意stderr沒有緩衝,您可以檢查是否問題是通過打印到stderr而不是stdout來緩衝。正如你所注意到的,你也可以使用stdbuf(更多信息請登錄this answer)。

+0

如果您編輯您的答案以包含此:http://stackoverflow.com/a/11337109/2550808我會接受它 – wick