带有数据文件的命令行参数

时间:2010-10-26 05:39:12

标签: c command-line-arguments

如果我想传递程序数据文件,我如何区分它们是数据文件的事实,而不仅仅是文件名的字符串。基本上我想文件重定向,但使用命令行参数,所以我可以肯定输入是正确的。

我一直在使用:

./theapp < datafile1 < datafile2 arg1 arg2 arg3 > outputfile

但我想知道它看起来像这样:

./the app datafile1 datafile2 arg1 arg2 arg3 > outputfile

允许使用命令行参数。

2 个答案:

答案 0 :(得分:3)

将两个文件组合成这样的标准输入有点困难。更好的是:

cat datafile1 datafile2 | ./theapp arg1 arg2 arg3 >outputfile

使用bash(至少),第二个输入重定向会覆盖第一个,但不会对其进行扩充。您可以使用以下两个命令查看:

cat <realfile.txt </dev/null # no output.
cat </dev/null <realfile.txt # outputs realfile.txt.

使用重定向时,您的应用程序甚至不会看到 >outputfile(例如)。它由shell进行评估,打开它并将其连接到您尝试运行的进程的标准输出。您的所有程序通常会看到:

./theapp arg1 arg2 arg3

与标准输入相同,它由shell处理。

上面第一个命令唯一可能的问题是它将两个文件组合成一个流,这样你的程序就不会知道第一个结束和第二个结束的位置(除非它能以某种方式从文件内容中推断出这一点) )。

如果你想处理多个文件并知道它们是哪个,那么做一些历史悠久的传统就是:

 ./theapp arg1 arg2 arg3 @datafile1 @datafile2 >outputfile

然后打开您的应用程序并自行处理文件。这比使shell更好地工作。

答案 1 :(得分:1)

从程序的角度来看,所有命令行参数都是字符串,您必须自己决定它们是否代表文件名。在Unix上只有两个字节不能出现在文件名中:0x00和0x2F(NUL/)。 [我的意思是 bytes 。除了HFS +之外,Unix文件系统完全无视字符编码,当然,合理的人使用UTF-8。]

Shell重定向根本不会出现在argv中。

但是有一个约定:将不以短划线开头的argv的每个元素(当然除argv[0])作为要处理的文件的名称,按顺序处理出现。你不必做任何不引用的操作;只需将它们原样传递给fopen(或open)即可。如果字符串"-"显示为argv的元素,则在该点处理标准输入直到用尽,然后继续循环argv。如果字符"--"出现在argv中,请将该点后的所有内容视为文件名,无论它是否以短划线开头。 (包括后续出现"-""--")。

根据您使用的语言,可能会有一个方便的库模块甚至语言原语来处理这些内容。例如,在Perl中,您只需编写

for (<>) {
   ... do stuff with $_ ...
}

你可以免费获得我在“有一个会议......”段落中所说的一切。 (但你说C,所以,嗯,你必须自己完成大部分工作。我不知道普通C的参数处理库值得在磁盘上占用空间。:-()