C ++中可变数量的命令行参数

时间:2014-04-15 17:53:28

标签: c++ arguments

我有一个程序(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陈述。

所以我的问题是:如何最好地处理可变数量的参数?

4 个答案:

答案 0 :(得分:1)

最常见的方法是编写一个处理命令行参数的特殊方法。您给它argcargv,它返回一组结构化的数据值。 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() {}
} ;

通过这种方式,您可以将所有参数传递给您的函数,而不是逐个列出它们。

只是一个想法...