15

我似乎无法像从命令行那样从配置文件中读取多令牌选项。配置文件的语法是什么?

这是添加选项描述的方式:

//parser.cpp
- - -
po::options_description* generic;
generic=new po::options_description("Generic options");
generic->add_options()
("coordinate",po::value<std::vector<double> >()->multitoken(),"Coordinates (x,y)");

之后我解析命令和配置文件。

在命令行 '--coordinate 1 2' 有效。但是,当我尝试在配置文件中:

coordinate = 1,2

或者

coordinate= 1 2

它未能给出 invalid_option_value 异常。那么在多令牌选项的情况下,配置文件的语法到底是什么?

4

3 回答 3

11

在您的配置文件中,将向量的每个元素放在不同的行上。

coordinate=1
coordinate=2
于 2011-12-16T13:43:38.820 回答
6

您可以通过编写自定义验证器来实现您寻求的行为。此自定义验证器接受:

./progname --coordinate 1 2
./progname --coordinate "1 2"
#In config file:
coordinate= 1 2

这是代码:

struct coordinate {
  double x,y;
};

void validate(boost::any& v,
  const vector<string>& values,
  coordinate*, int) {
  coordinate c;
  vector<double> dvalues;
  for(vector<string>::const_iterator it = values.begin();
    it != values.end();
    ++it) {
    stringstream ss(*it);
    copy(istream_iterator<double>(ss), istream_iterator<double>(),
      back_inserter(dvalues));
    if(!ss.eof()) {
      throw po::validation_error("Invalid coordinate specification");
    }
  }
  if(dvalues.size() != 2) {
    throw po::validation_error("Invalid coordinate specification");
  }
  c.x = dvalues[0];
  c.y = dvalues[1];
  v = c;
}
...
    po::options_description config("Configuration");
    config.add_options()
        ("coordinate",po::value<coordinate>()->multitoken(),"Coordinates (x,y)")
        ;

参考:

于 2011-05-04T15:14:03.673 回答
0

在发现自己遇到类似问题的过程中,我从 Rob 的回答(从 2011 年 5 月 4 日开始)中获取了上面的代码,但由于 boost 架构和 C++11 的变化而不得不更改一些内容。我只引用我改变(或将改变)的部分。不在 validate 函数中的其余部分保持不变。出于一致性原因,我添加了必要的 std:: 前缀。

namespace po = boost::program_options;

void validate(boost::any& v,
  const std::vector<std::string>& values,
  coordinate*, int) {
  coordinate c;
  std::vector<double> dvalues;
  for(const auto& val : values)  {
    std::stringstream ss(val);
    std::copy(std::istream_iterator<double>(ss), std::istream_iterator<double>(),
      std::back_inserter(dvalues));
    if(!ss.eof()) {
      throw po::invalid_option_value("Invalid coordinate specification");
    }
  }
  if(dvalues.size() != 2) {
    throw po::invalid_option_value("Invalid coordinate specification");
  }
  c.x = dvalues[0];
  c.y = dvalues[1];
  v = c;
}

在https://stackoverflow.com/a/12186109/4579106中暗示了从 po::validation_error 到 po::invalid_option_value 的转变

于 2016-09-01T13:59:58.780 回答