boost::program_options config file option with multiple tokens

前端 未结 3 1432
迷失自我
迷失自我 2021-02-07 10:17

I can not seem to be able to read from config file multitoken options like I can from command line. What is the syntax for the config file?

This is how the option descri

相关标签:
3条回答
  • 2021-02-07 10:29

    You can achieve the behavior you seek by writing a custom validator. This custom validator accepts :

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

    Here is the code:

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

    References:

    • http://www.boost.org/doc/libs/1_46_1/doc/html/program_options/howto.html#id2219998
    • https://stackoverflow.com/tags/boost-program-options/hot
    • Handle complex options with Boost's program_options
    0 讨论(0)
  • 2021-02-07 10:36

    In your configuration file, put each element of your vector on a different line.

    coordinate=1
    coordinate=2
    
    0 讨论(0)
  • 2021-02-07 10:41

    During finding myself confronted with a similar problem, I took the code above from Rob's answer (from May 4th, 2011), but had to change a few things due to changes in the boost architecture and C++11. I only cite the parts that I changed (or would have changed). The rest that is not within the validate function stays the same. For conformity reasons, I added the necessary std:: prefixes.

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

    The shift from po::validation_error to po::invalid_option_value was hinted in https://stackoverflow.com/a/12186109/4579106

    0 讨论(0)
提交回复
热议问题