我有一个程序(myprogram
),它接受一个文件输入并创建另一个输出文件。语法是:
myprogram inputfile outputfile
它看起来像这样:
int main ( int argc, char *argv[] )
{
...
if ( argc != 3 ) {
cout<<"wrong number of arguments"<< endl; return 1;}
}
myInputFile = argv[1];
myOutputFile = argv[2];
...
}
所以这里我有argv[1]
作为输入文件。我现在想在语法中添加一些选项。所以,例如,我希望myprogram -a inputfile outputfile
作为选项。选项的数量会有所不同。
这意味着文件名将取决于参数的数量。
在代码中执行此操作的最明智的方法是什么?我可以看到,只会将最后两个参数作为文件名,然后假设之前的参数是选项(类似于myInputFile = argv[argc - 1]
。这不是很正确,因为我最终得到了很多if ... then
陈述。
所以我的问题是:如何最好地处理可变数量的参数?
答案 0 :(得分:1)
最常见的方法是编写一个处理命令行参数的特殊方法。您给它argc
和argv
,它返回一组结构化的数据值。 e.g。
struct commands
{
char* InputFile;
char* OutputFile;
bool WhateverAMeans;
};
这样你的主循环就有了足够的东西列表,并且不需要大量的循环。
通常,您的方法将使用for循环迭代参数以填充命令。
或者,存在帮助您完成此工作的帮助程序类,但我不建议在很长时间内没有这样做。
答案 1 :(得分:1)
如果你不介意我建议一个处理所有这些问题的图书馆。试试Boost.Program Options。它可能看起来比你预期的要复杂,但它足够强大。还有很多 C 库,比如getopt,popt和其他许多
答案 2 :(得分:1)
看看boost :: program_options,非常有用且干净的工具。 我也使用过Poco :: OptionSet,但它对我来说不是那么干净,因为提升。 Poco和boost都需要由你构建,但如果你从未使用过它们 - 这是很好的开始机会,它们都很棒。
答案 3 :(得分:1)
如果您不想使用库,那该怎么做:
char* myInputFile = NULL ;
char* myOutputFile = NULL ;
bool option_a = false ;
int argi = 1 ;
while ( argi < argc )
{
const char* args = argv[ argi++ ] ;
switch ( *args )
{
case '-' : /* option/switch */
if ( strcmp( args, "-a" ) == 0 )
option_a = true ;
else
{
std::cerr << "Unknow option " << args << "\n" ;
exit( 1 ) ;
}
break ;
default :
if ( myInputFile == NULL )
myInputFile = args ;
else if ( myOutputFile == NULL )
myOutputFile = args ;
else
{
std::cerr << "Unexpected argument " << args << "\n" ;
exit( 1 );
}
break ;
}
}
最后,当您处理所有参数时,您可以进行一些最终检查,例如,测试是否设置了输入文件和输出文件:
if ( myInputFile == NULL )
{
std::cerr << "Input file missing!\n" ;
exit( 1 ) ;
}
...
您也可以将所有参数放入结构中,而不是单独使用它们:
struct options_t
{
char* myInputFile ;
char* myOutputFile ;
bool option_a ;
options_t() : myInputFile(), myOutputFile(), option_a() {}
} ;
通过这种方式,您可以将所有参数传递给您的函数,而不是逐个列出它们。
只是一个想法...