опция файла конфигурации boost :: program_options с несколькими токенами - PullRequest
15 голосов
/ 04 мая 2011

Кажется, я не могу читать из файла конфигурации опции мультитокена, как могу из командной строки Какой синтаксис для конфигурационного файла?

Вот как добавляется описание опции:

//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. Так что же такое синтаксис для конфигурационных файлов в случае опций мультитокена?

Ответы [ 3 ]

9 голосов
/ 16 декабря 2011

В вашем файле конфигурации поместите каждый элемент вашего вектора в отдельную строку.

coordinate=1
coordinate=2
6 голосов
/ 04 мая 2011

Вы можете добиться желаемого поведения, написав собственный валидатор.Этот пользовательский валидатор принимает:

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

Список литературы:

0 голосов
/ 01 сентября 2016

Во время того, как я столкнулся с подобной проблемой, я взял приведенный выше код из ответа Роба (от 4 мая 2011 года), но мне пришлось изменить некоторые вещи из-за изменений в архитектуре boost и C ++ 11.Я цитирую только те части, которые я изменил (или изменил бы).Остальное, что не входит в функцию проверки, остается прежним.По соображениям соответствия я добавил необходимые префиксы 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;
}

Переход от po :: validation_error к po :: invalid_option_value был подсказан в https://stackoverflow.com/a/12186109/4579106

...