C++: Boost program_options: Multiple lists of arguments

后端 未结 1 1683
星月不相逢
星月不相逢 2020-12-11 10:18

I\'m currently working with boost::program_options. My program is supposed to take as arguments (amongst other things...) an arbitrary number of \'lists\' of ar

相关标签:
1条回答
  • 2020-12-11 10:43

    This can be done without a whole lot of extra code. The secret is to separate the parsing step from the storage step, as also done in this answer.

    The parser will return a container of key/value structs as the options are presented from the user. If an option is submitted multiple times then the container will have a separate entry for each option submission. It is quite straightforward to scan for a particular option and organize its values however we want.

    Here's an example that prints out each input multi-token option 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's a sample invocation (live at coliru):

    $ ./po --list 1 2 3 --list foo bar --list how now brown cow
    1 2 3 
    foo bar 
    how now brown cow 
    
    0 讨论(0)
提交回复
热议问题