2

我正在使用 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

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

4

2 回答 2

2

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

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

代码示例

结果:

./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
于 2013-07-19T09:20:08.303 回答
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当给出太多位置参数时,会抛出一个实例。

于 2017-07-10T12:57:22.047 回答