2017-06-14 108 views
-1

我正在運行一個C程序(在Ubuntu - bash終端上),它需要3個文件的輸入 - f1, f2, f3將多個文件重定向到stdin

for(...) 
    scanf(....)//reads input from f1 
for(...) 
    scanf(....)//reads input from f2 
for(...) 
    scanf(....)//reads input from f3 

我想用重定向操作上的bash提供輸入到C程序。

但是,如果我跑我的程序如下,我能夠從只有1個讀取文件:

./a.out < f1 

怎樣的f1, f2,f3輸入重定向到我的C程序?

+1

不是'C'的問題,但答案是'cat',對於串聯流中的\ * nix的工具。 '貓f1 f2 f3 | 。/ a.out'完成這項工作。 –

+0

@FelixPalmen當然,但他將無法區分文件。我認爲這個問題說得不好...... –

+0

@示例代碼中的Jean-BaptisteYunès,看起來他已經知道了。否則,這應該是嘗試從'stdin'讀取的第一個疑問。 –

回答

4

通常情況下,你只使用標準輸入重定向(FD 0,與<重定向運算符),標準輸出(fd 1,>)和標準錯誤(fd 2,2>),這似乎限制您只有一個輸入流。

(當然你可以不喜歡cat f1 f2 f3 | program,而是告訴文件除了會很難。)

但是,如果你真的真的想,你可以使用其他文件描述符號碼輸入了。這與重定向stderr時的相同方式完成,只需在重定向操作符之前添加該數字即可。因此,運行

./prog 3<file1 4<file2 5< file3 

會在打開給定文件FD的3,4和5,並通過那些上./prog。該程序然後可以使用fdopen將stdio流(FILE *)與它們相關聯。這裏最大的問題是你需要一些方法來知道在程序中使用哪個fd,這很快就會需要使用諸如命令行參數之類的東西。下面的玩具例子是固定使用這三個fd的,當然這並不是一成不變的。

相反,你最好做所有其他程序做的事,並將文件名作爲命令行參數傳遞。即使在需要引用已經打開的文件描述符的情況下,許多Unix也可以通過名稱來引用它們:/dev/fd/1等(Process substitution,它就像一個普通的管道,是需要的東西之一要做到這一點)


fdopen()例如:

#include <stdio.h> 

void read_a_line(int fd) 
{ 
    char buf[64]; 
    FILE *f = fdopen(fd, "r"); 
    fgets(buf, 64, f); 
    printf("fd %d: %s\n", fd, buf); 
    fclose(f); 
} 

int main(void) 
{ 
    read_a_line(3); 
    read_a_line(4); 
    read_a_line(5); 
    return 0; 
} 
+0

謝謝!是的,僅僅使用帶有文件名的命令行參數是有意義的。 –

1

我想你可能要找的功能是getopt。這樣,你可以使用命令行參數而不是重定向(僅用於一個輸入流)三個文件到你的程序中。然後,只需調用它是這樣的:

./a.out f1 f2 f3 

此外,我剛纔看到this question,它採用這樣的結構:

#include <stdio.h> 
int main(int argc, const char* argv[]) { 
    for(int i = 1; i < argc; i++) { 
     //work with each file name 
     //note that argv[0] is: ./a.out 
    } 
} 
+1

您不需要'getopt'處理一個簡單的文件名列表。但是,當然,當你想支持標誌時,它開始變得有用。 'main'的參數的習慣名稱是'argc'和'argv',即'int main(int argc,char * argv [])',它可能是一個非常好的主意,它會使它更容易與其他人的代碼一起工作。 ([看起來](https://stackoverflow.com/a/2108208/6372809)在語言標準中提到了特定簽名,但它沒有明確要求它。) – ilkkachu

+0

編輯我的答案以反映約定,謝謝。 – Peri461

相關問題