Boost :: Program_options,传递一个未知的命令行参数

时间:2013-07-19 09:10:32

标签: c++ boost boost-program-options

我正在使用boost :: program_options为我的程序传递配置文件。特别是我经常使用命令行覆盖某些选项。例如,如果我注册两个选项“opt1”和“opt2”,我可以通过运行我的程序

成功覆盖默认值
 myProgram.exe --opt1=option_value_1 --opt2=option_value_2

一切都很好,但是我已经很少次将我的程序错误地用作

 myProgram.exe --opt1=option_value_1 opt2=option_value_2

在这种情况下(缺少双连字符)不会引发错误。事实上,我显然可以将myProgram作为

运行
 myProgram.exe list of any unregistered and unknown values

它仍然可以正常运行。我希望至少得到意外发生的事情。我的问题有解决方案吗?

2 个答案:

答案 0 :(得分:1)

您应该从解析命令中删除allow_unregistered()。你的命令应该只是

po::store(parse_command_line(argc, argv, desc), vm);

然后会在未知选项上抛出异常。

http://www.boost.org/doc/libs/1_54_0/doc/html/program_options/howto.html#idp123440592

如果您想要异常/错误,如果选项没有“ - ”,您应该编写额外的解析器,这样的东西,可以帮助您

std::pair<std::string, std::string> fix_option(const std::string& value)
{
   std::string name = value;
   std::string val;
   std::string::size_type pos = name.find("=");
   if (pos != std::string::npos)
   {
      val = name.substr(pos + 1);
      name = name.substr(0, pos);
   }
   if (name.substr(0, 2) != "--")
   {
      throw std::logic_error(std::string("invalid command, no -- in command: ") + name);
   }
   return std::make_pair(name.substr(2), val);
}

code example

结果:

./new --help=j

output: j

./new help=j

output: 
terminate called after throwing an instance of 'std::logic_error'
  what():  invalid command, no -- in command: help

答案 1 :(得分:0)

似乎boost::program_options无法识别默认位置参数。这意味着忽略了opt2=option_value_2之类的非选项参数。但是,文档并不清楚。您可以使用basic_command_line_parser::positional()启用位置参数的处理。

按示例

try {
    po::variables_map vm;
    po::store(po::command_line_parser(argc, argv).
                options(desc).positional({}).run(),
              vm);
    po::notify(vm);
} catch (po::too_many_positional_options_error &e) {
    // A positional argument like `opt2=option_value_2` was given
    cerr << e.what() << endl;
    exit(1);
} catch (po::error_with_option_name &e) {
    // Another usage error occurred
    cerr << e.what() << endl;
    exit(1);
}

解释

基本上,

po::store(po::parse_command_line(argc, argv, desc), vm);

已替换为

po::store(po::command_line_parser(argc, argv)
            .options(desc).positional({}).run(),
          vm);

据我了解文档,parse_command_line(argc, argv, desc)command_line_parser(argc, argv).options(desc).run()的简写。通过添加对positional()的调用,我们可以处理位置参数。通过指定{},不允许任何位置参数。当给出太多位置参数时,抛出too_many_positional_options_error的实例。