1

is it possible to parse multiple mulit-token parameters with the same name?

Like: program.exe --param a b c --param foo bar ?

I only could get it to work like this: program.exe --param "a b c" --param "foo bar" but then I have to split the parameter myself.

[...] options.add_options()("param", po::value<vector<string>>()->multitoken() , "description") [...] 

thanks for any hints

2
  • Why don't you show the code that you used? It's a bit ... I dunno to claim "I could get it to work like this", but then not share it. It burdens any answerers with redoing all that work for you? Commented Nov 20, 2022 at 20:07
  • Sorry, I forgot to paste the code :/ Commented Nov 21, 2022 at 5:26

1 Answer 1

1

I think you want a combination of composing and multi-token:

Live On Coliru

#include <boost/program_options.hpp> #include <fmt/ranges.h> namespace po = boost::program_options; using strings = std::vector<std::string>; int main(int argc, char** argv) { po::options_description opts; opts.add_options()("param", po::value<strings>() ->multitoken() ->composing() ->default_value({}, "") ->implicit_value({}, ""), "you know the drill"); po::variables_map vm; store(parse_command_line(argc, argv, opts), vm); if (vm.contains("param")) { fmt::print("Params: {}\n", vm["param"].as<strings>()); } } 

Which prints e.g.:

+ ./a.out Params: [] + ./a.out --param Params: [] + ./a.out --param a b Params: ["a", "b"] + ./a.out --param a b --param c d Params: ["a", "b", "c", "d"] 

Note, if you don't want to allow --param without a value, remove the implicit_value: Live On Coliru

UPDATE

To the comment:

You can always use the parser section of the library, inspecting the parsed_options instance:

// using parsed-options to see "source" material: auto parsed = parse_command_line(argc, argv, opts); for (auto& po : parsed.options) { auto key = po.position_key == -1 // ? po.string_key : '#' + std::to_string(po.position_key); fmt::print("Option {}: {}\n", key, po.value); } // original logic: store(parsed, vm); if (vm.contains("param")) { fmt::print("Effective combined params: {}\n", vm["param"].as<strings>()); } 

See it Live On Coliru, printing:

+ ./a.out Effective combined params: [] + ./a.out --param Option param: [] Effective combined params: [] + ./a.out --param a b Option param: ["a", "b"] Effective combined params: ["a", "b"] + ./a.out --param a b --param c d Option param: ["a", "b"] Option param: ["c", "d"] Effective combined params: ["a", "b", "c", "d"] 
Sign up to request clarification or add additional context in comments.

4 Comments

Hi, thanks for the hint. I think I not not have been clear enough, sorry about that. This way I get all the "param" tokens but I cannot distinguish which where the first param and the second.
That's the whole purpose of the library, and specifically variable_map: it allows you to consume option values regardless of the source (it can be from a config file, a command line or several at the same time). See e.g. stackoverflow.com/a/72807837/85371, stackoverflow.com/a/70102829/85371 and this one that contains a little more background about the library's design: stackoverflow.com/a/62433436/85371
You can always use the parser section of the library, inspecting the parsed_options instance: added a demo also Live On Coliru to the answer.
Ah, that's what I was looking for. Thanks for the tip and the links :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.