2015-09-01 77 views
3

我有一個非常簡單的程序:當我使用'|'時會發生什麼?或「<」,C++

void main() 
{ 
    fgets(buf,133,stdin); 
    printf(buf); 
    system("/bin/dash"); 
} 

當我啓動程序,這一切工作正常,我可以輸入任何我想要的,然後我有一個殼。但是,如果我爲了自動補BUF(不使用鍵盤打字點兒)做

$ echo 'blabla' | ./test 

,外殼被執行,但是,/ bin中/ LS工作正常的情況下。 (顯然的顯示命令的工作精細)

如果刪除了與fgets線,並且我執行相同的命令,它的工作原理,但需要的「布拉布拉」作爲/斌/破折號的參數。然而,添加一個nul字符或返回'\ xd'來模擬我的鍵盤在fgets中的返回不起作用

我想了解當我使用'|'時會發生什麼,符號在我的C++程序中。我認爲這是在沒有任何人爲干預的情況下自動填充scanfs和fgets的解決方案,我是做錯了還是有其他解決方案?

謝謝。

的Debian,C++ G ++

+2

在標準C++主總是返回'int' – NathanOliver

+1

HTTP://meta.stackexchan ge.com/questions/66377/what-is-the-xy-problem? –

+0

['void main()'](http://stackoverflow.com/q/204476/995714)是錯誤的 –

回答

2

如果我理解正確的話,你想既您fgets和你的shell提供輸入,而是發現,當外殼沒有收到任何輸入你管。

這是因爲會的libc緩衝輸入數據以便fgets

代替讀出7個字節在blabla\n,其餘傳遞到外殼,它讀取可達4096個字節(依賴於系統),並使用剩餘的4089個字節用於在stdin未來fgets/f*呼叫。這些數據將被內部存儲在您的程序中,並且不會被其他從底層流中讀取的進程使用,如被調用的shell。

當您交互式運行並在鍵盤上鍵入時,只有7個字節 在您按回車時可用,所以緩衝區只填充7個字節。您鍵入的其餘數據因此可用於shell。你可以有模擬同樣的效果在你的錯誤的程序與輸入戰略地位延遲:

{ echo "for fgets"; sleep 1; echo "ls"; } | ./foo 

您可以通過設置緩衝區大小爲1個字節規避這個問題,讓fgets從不讀取超過必要的:

#include <stdio.h> 

char input_buffer[1]; 

void main(int argc, char** argv) 
{ 
    char buf[133]; 
    setvbuf(stdin, input_buffer, _IOFBF, 1); 
    fgets(buf,133,stdin); 
    printf(buf); 
    system("/bin/dash"); 
} 

現在你可以用一個管和沒有延遲運行它:

$ echo -e "for fgets\nls" 
for fgets 
ls 
$ gcc foo.c -o foo 
$ echo -e "for fgets\nls" | ./foo 
for fgets 
Desktop Downloads foo.c Pictures Steam  Videos 
Documents foo  Music Public Templates win 
+0

非常感謝!事情是,我想自動完成不是由我寫的程序,所以我不能使用setvbuf,但是謝謝你教我如何使用fgets。我試着像你說的那樣睡覺,它很有效。 – x4rkz

+0

耶!但是,如果您嘗試自動輸入二進制文件,您無法修改,我會建議您發佈一個新問題,說您要將輸入自動化爲無法修改的二進制文件。您將以這種方式獲得更優雅和強大的答案。 –

5

當執行在shell echo 'blabla' | ./test,殼將啓動echo過程和它的標準輸出管連接到的./test標準輸入管。這與C++無關:這些管道是大多數操作系統的一個特性,幾乎每個進程都有它們。

當您的程序執行system時,您正在創建與相同的標準輸入管道連接的新進程(或多個進程)。所以,如果有該管(從echo命令)的一些數據尚未閱讀test,這將提供給你所開始system的進程讀取。

使用echo和管道是提供輸入到fgetsscanf的好方法。將數據傳遞到程序的另一種方法是使用環境變量或命令行參數,但您需要修改代碼以檢查這些內容。

+0

我知道管道不是C++相關的,我只想自動填充任何語言的scanf,但我想給一個具體的例子。感謝您的解釋,但是我們的目標是自動填充scanf並非由我編寫的程序,因此使用環境並且修改代碼不是一種選擇。 – x4rkz

相關問題