вектор значений boost :: program_options с zero_token - PullRequest
4 голосов
/ 30 марта 2011

Я пытаюсь разобрать следующий синтаксис с boost :: program_options:

a)
$ a.out
verbosity: 0

b)
$ a.out -v
verbosity: 1

c)
$ a.out -v -v
verbosity: 2

d)
$ a.out -vv
verbosity: 2

e) (optional)
$ a.out -v3
verbosity: 3

Моя программа пока:

#include <iostream>
#include <boost/program_options.hpp>
namespace po = boost::program_options;

int main(int argc, char *argv[])
{
    po::options_description desc;
    desc.add_options()
        ("verbose,v", po::value<int>(), "verbose");
    po::variables_map vm;
    po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
    po::notify(vm);

    std::cout << "verbosity: " << vm["verbose"].as<int>() << std::endl;

    return 0;
}

Это работает только для e).Если я изменю его на:

po::value<int>()->default_value(0)

, это будет работать для а) и е).С

po::value<int>()->default_value(0)->implicit_value(1)

это работает для a), b) и e).

Как я могу получить его для анализа всех вышеупомянутых случаев?

Я думаю, что янужна некоторая комбинация вектора значений с zero_tokens (), но я не могу заставить его работать.

Ответы [ 2 ]

1 голос
/ 31 марта 2011

Хотя это не красиво, это решает мой оригинальный вопрос:

#include <iostream>
#include <vector>
#include <string>
#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>
namespace po = boost::program_options;

std::pair<std::string, std::string> verbosity(const std::string& s)
{
    if(s.find("-v") == 0)
    {
        size_t value = 1;
        try {
            value = boost::lexical_cast<size_t>(s.substr(2));
        }
        catch(...)
        {
            while(s[1+value] == 'v')
                ++value;
        }
            return std::make_pair("verbose", boost::lexical_cast<std::string>(value));
    }
    return std::make_pair(std::string(), std::string());
}

int main(int argc, char *argv[])
{
    po::options_description desc;
    desc.add_options()
        ("verbose,v", po::value<std::vector<std::string> >(), "verbose");
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc, 0, verbosity), vm);
    po::notify(vm);

    size_t verbosity = 0;
    if(vm.count("verbose"))
        BOOST_FOREACH(const std::string& s, vm["verbose"].as<std::vector<std::string> >())
            verbosity += boost::lexical_cast<int>(s);
    std::cout << "verbosity: " << verbosity << std::endl;

    return 0;
}
1 голос
/ 30 марта 2011

чтобы получить количество аргументов -v, используйте vm ["verbose"]. Count. конечно, это приведет к некоторым странным результатам при объединении с методом vm ["verbose"]. as <> ().

чтобы действительно делать то, что вы хотите, вам, вероятно, придется написать свой собственный метод синтаксического анализа для этой опции. функция будет выглядеть примерно так:

std::pair<std::string, std::string> verbosity_count(const std::string& s)
{
    if(s.find("-v") || s.find("--verbose"))
    {
       // process the verbosity count (this will require a static verbosity count var)
       return std::make_pair("-v", value as string);
    }
    else
    {
       return std::make_pair(std::string(), std::string());
    }
    return std::make_pair(std::string(), std::string());
 }

вы бы прикрепили это к анализатору командной строки с помощью метода extra_parser () (подробные сведения см. В документации к форсированной версии программы Program Program).

...