Boost :: program_options vector of values ​​with zero_token

I am trying to get the following syntax with 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 

My program:

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

This only works for e). If I change it to:

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

works for a) and e). WITH

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

it works for a), b) and e).

How can I get him to analyze all the above cases?

I think I need a combination of a vector of values ​​with zero_tokens (), but I can't get it to work.

+4
source share
2 answers

Until it is beautiful, this solves my initial question:

 #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
source

to get the number of arguments -v, use vm ["verbose"]. count. of course, this will lead to some strange results when combined with the vm ["verbose"] method as <> ().

in order to really do what you want, you probably have to write your own parsing method for this parameter. the function will look something like this:

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

you attach this to the command line parser using the extra_parser () method (see the extended program options documents for exact details, their long and messy ones).

+1
source

Source: https://habr.com/ru/post/1345880/


All Articles