C ++: Boost program_options: multiple argument lists

I am currently working with boost::program_options. My program should take as arguments (among other things ...) an arbitrary number of "lists" of arbitrary length. For example, the user should be able to call

./myprogram -list item1 item2 item3 -list item1 item2 -list item1 item2

Obviously, I do not want to get one list / vector with all the elements one after another as a result, but (in this case) three lists / vectors (or, for example, one vector of vectors containing elements) with two or three elements in the list ( each element should be a string, but I think it doesn't matter). As I said, the number of lists (as well as the number of elements in the list!) Must be arbitrary. How to do this with boost::program_options?

+2
source share
1 answer

This can be done without a lot of additional code. The secret is to separate the parsing step from the storage phase, just like in this answer .

The parser will return a container with keys / values, since the parameters are presented from the user. If the parameter is passed several times, then the container will have a separate entry for each parameter feed. It is very simple to scan a specific option and arrange its values, but we want to.

Here is an example that prints each input parameter of several tokens on a separate line:

#include <iostream>
#include <string>
#include <vector>

#include <boost/program_options.hpp>

namespace po = boost::program_options;

int main(int argc, char *argv[]) {
   // Define a multi-token option.
   po::options_description desc("Allowed options");
   desc.add_options()
      ("list", po::value<std::vector<std::string>>()->multitoken(), "multiple values");

   // Just parse the options without storing them in a map.
   po::parsed_options parsed_options = po::command_line_parser(argc, argv)
      .options(desc)
      .run();

   // Build list of multi-valued option instances. We iterate through
   // each command-line option, whether it is repeated or not. We
   // accumulate the values for our multi-valued option in a
   // container.
   std::vector<std::vector<std::string>> lists;
   for (const po::option& o : parsed_options.options) {
      if (o.string_key == "list")
         lists.push_back(o.value);
   }

   // If we had other normal options, we would store them in a map
   // here. In this demo program it isn't really necessary because
   // we are only interested in our special multi-valued option.
   po::variables_map vm;
   po::store(parsed_options, vm);

   // Print out the multi-valued option, each separate instance on its
   // own line.
   for (size_t i = 0; i < lists.size(); ++i) {
      for (size_t j = 0; j < lists[i].size(); ++j)
         std::cout << lists[i][j] << ' ';
      std::cout << '\n';
   }

   return 0;
}

And here is an example of invocation ( lives in coliru ):

$ ./po --list 1 2 3 --list foo bar --list how now brown cow
1 2 3 
foo bar 
how now brown cow 
+3

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


All Articles