【问题标题】:boost::program_options config file option with multiple tokensboost::program_options 具有多个标记的配置文件选项
【发布时间】:2023-03-11 20:59:01
【问题描述】:

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

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

//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 异常失败。那么在多令牌选项的情况下,配置文件的语法到底是什么?

【问题讨论】:

  • 这里不需要使用new。如果这样做,则可能会发生内存泄漏。

标签: c++ syntax boost-program-options optionparser configuration-files


【解决方案1】:

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

coordinate=1
coordinate=2

【讨论】:

    【解决方案2】:

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

    ./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)")
            ;
    

    参考资料:

    【讨论】:

      【解决方案3】:

      在发现自己遇到类似问题的过程中,我从 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 的转变

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-02
        相关资源
        最近更新 更多