2017-06-14 125 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