【问题标题】:C++: Boost program_options: Multiple lists of argumentsC++:Boost program_options:多个参数列表
【发布时间】:2016-02-01 14:52:08
【问题描述】:

我目前正在与boost::program_options 合作。我的程序应该将任意数量的任意长度的“列表”作为参数(除其他外......)。例如,用户应该能够调用

./myprogram -list item1 item2 item3 -list item1 item2 -list item1 item2

显然,我不想得到一个列表/向量,其中所有项目一个接一个,但是(在这种情况下)三个列表/向量(或者,例如,一个向量包含元素)每个列表有两个或三个项目(每个项目应该是一个字符串,但我想这并不重要)。 正如我之前所说,列表的数量(以及每个列表的项目数!)应该是任意的。 我如何使用boost::program_options 做到这一点?

【问题讨论】:

  • AFAIK 没有直接的方法可以做到这一点,因为每个itemn 都将被视为一个单独的选项。您可以做的一件事是定义一个名为“list”的选项,其类型为vector<string>,然后在您传递参数时,传递一个分隔字符串,例如-list "item1,item2,item3" -list "item4,item5" -list "item1,tem2"
  • 好吧,如果真的没有其他方法我会考虑这样做,但我实际上认为这对用户来说非常复杂而且很不雅。
  • 我之前尝试过做类似的事情,但没有成功。虽然 Boost 程序选项非常适合解决更简单的问题,但一旦您发现用例或需要不支持的东西,您基本上必须放弃它并编写自己的命令行参数处理。

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


【解决方案1】:

这可以在没有大量额外代码的情况下完成。秘诀是将解析步骤与存储步骤分开,就像this answer 中所做的那样。

当用户提供选项时,解析器将返回一个键/值结构的容器。如果一个选项被多次提交,那么容器将为每个选项提交一个单独的条目。扫描特定选项并根据需要组织其值非常简单。

这是一个在单独的行上打印出每个输入多令牌选项的示例:

#include <iostream>
#include <string>
#include <vector>

#include <boost/program_options.hpp>

namespace po = boost::program_options;

int main(int argc, char *argv[]) {
   // Define a multi-token option.
   po::options_description desc("Allowed options");
   desc.add_options()
      ("list", po::value<std::vector<std::string>>()->multitoken(), "multiple values");

   // Just parse the options without storing them in a map.
   po::parsed_options parsed_options = po::command_line_parser(argc, argv)
      .options(desc)
      .run();

   // Build list of multi-valued option instances. We iterate through
   // each command-line option, whether it is repeated or not. We
   // accumulate the values for our multi-valued option in a
   // container.
   std::vector<std::vector<std::string>> lists;
   for (const po::option& o : parsed_options.options) {
      if (o.string_key == "list")
         lists.push_back(o.value);
   }

   // If we had other normal options, we would store them in a map
   // here. In this demo program it isn't really necessary because
   // we are only interested in our special multi-valued option.
   po::variables_map vm;
   po::store(parsed_options, vm);

   // Print out the multi-valued option, each separate instance on its
   // own line.
   for (size_t i = 0; i < lists.size(); ++i) {
      for (size_t j = 0; j < lists[i].size(); ++j)
         std::cout << lists[i][j] << ' ';
      std::cout << '\n';
   }

   return 0;
}

这是一个示例调用 (live at coliru):

$ ./po --list 1 2 3 --list foo bar --list how now brown cow
1 2 3 
foo bar 
how now brown cow 

【讨论】:

    猜你喜欢
    • 2011-02-02
    • 1970-01-01
    • 2016-02-22
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多