简体   繁体   English

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

[英]Variable number of command line arguments in C++

I have a program ( myprogram ) that takes a file for input and creates another file for output. 我有一个程序( myprogram ),该程序接受一个文件作为输入,并创建另一个文件作为输出。 The syntax is: 语法为:

myprogram inputfile outputfile

It looks something like this: 看起来像这样:

int main ( int argc, char *argv[] )
{
...  
if ( argc != 3 ) {
    cout<<"wrong number of arguments"<< endl; return 1;}
   }
myInputFile = argv[1];
myOutputFile = argv[2];
...
}

So here I have argv[1] being the inputfile.I would now like to add some options to the syntax. 所以这里我有argv[1]作为输入文件。我现在想在语法中添加一些选项。 So, for example, I would like myprogram -a inputfile outputfile as an option. 因此,例如,我希望将myprogram -a inputfile outputfile作为选项。 The number of options will vary. 选项的数量会有所不同。

That means that the filenames will depend on the number of arguments. 这意味着文件名将取决于参数的数量。

What is the smartest way to do this in the code? 在代码中最聪明的方法是什么? I can see that one would just take the last two arguments as the filenames and then assume that the arguments before that are the options (so something like myInputFile = argv[argc - 1] . This doesn't quite feel right because I end up with a lot of if ... then statements. 我可以看到一个人只会将最后两个参数作为文件名,然后假定在那之前的参数是选项(所以类似myInputFile = argv[argc - 1] 。这感觉不太正确,因为我结束了有很多if ... then语句。

So my question is: How does one best deal with a variable number of arguments? 所以我的问题是:如何最好地处理可变数量的参数?

The most common way is to write a special method for handling the command line arguments. 最常见的方法是编写一种特殊的方法来处理命令行参数。 You give it argc and argv and it returns a structured set of data values. 您给它argcargv ,它返回一组结构化的数据值。 eg 例如

struct commands
{
    char* InputFile;
    char* OutputFile;
    bool WhateverAMeans;
};

This way your main loop has a sufficient list of things it requires and doesn't require tons of loops. 这样,您的主循环便具有所需清单,并且不需要大量的循环。

Typically your method would use a for loop to iterate over the arguments to fill in the commands. 通常,您的方法将使用for循环遍历参数以填充命令。

Alternatively there exist helper classes that do this work for you, although I cannot recommend any having not done this in a long time. 另外,也可以使用帮助程序类为您完成这项工作,尽管我不建议您使用很长时间没有做过的事情。

If you don't mind I'd suggest a library that deals w/ all these issues. 如果您不介意,我建议您使用一个处理所有这些问题的库。 Try Boost.Program Options . 尝试使用Boost.Program Options It might look too complex than you expected but it's powerful enough. 它看起来可能比您预期的要复杂,但功能足够强大。 Also there're a lot C libraries, like getopt, popt and many others 还有很多C库,例如getopt,popt等

Look at boost::program_options, very useful and clean tool for that. 看一下boost :: program_options,这是非常有用且干净的工具。 I also used Poco::OptionSet, but it wasn't so clean for me, as boost. 我还使用了Poco :: OptionSet,但对我来说不是那么干净,就像升压一样。 Both Poco and boost need to be build by you, but if you never used any of them - that is good chance to start, they both are awesome. Poco和boost都需要由您自己构建,但是如果您从未使用过它们-那是很好的开始机会,它们都很棒。

How about that in case you do not want to use libraries: 如果您不想使用库,该怎么办:

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 ;
   }
}

At the end, when you process all your arguments you can do some final checking like, for example, testing if the input file and output file were set: 最后,当您处理所有参数时,您可以进行一些最终检查,例如,测试是否设置了输入文件和输出文件:

if ( myInputFile == NULL )
{
    std::cerr << "Input file missing!\n" ;
    exit( 1 ) ;
}
...

You could also put all your arguments into a structure instead of having them separately: 您还可以将所有参数放入一个结构中,而不用将它们分开:

struct options_t
{
    char* myInputFile ;
    char* myOutputFile ;
    bool  option_a ;

    options_t() : myInputFile(), myOutputFile(), option_a() {}
} ;

This way you can pass all arguments down to your functions instead of listing them one by one. 这样,您可以将所有参数传递给函数,而不必一一列出。

Just a thought... 只是一个想法...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM