7

I want to parse multiple command line arguments using boost::program_options. However, some arguments are strings enclosed in double quotes. This is what I have -

void processCommands(int argc, char *argv[]) {
    std::vector<std::string> createOptions;
    boost::program_options::options_description desc("Allowed options");
    desc.add_options()
    ("create", boost::program_options::value<std::vector<std::string> >(&createOptions)->multitoken(), "create command")
    ;
    boost::program_options::variables_map vm;
    boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
    boost::program_options::notify(vm);
    if(vm.count("create") >= 1) {
        std::string val1 = createOptions[0];
        std::string val2 = createOptions[1];
        ...
        // call some function passing val1, val2.
    }
}

this works fine when I do

cmdparsing.exe --create arg1 arg2

But does not work when I do

cmdparsing.exe --create "this is arg1" "this is arg2"

from windows command line. For second option, it gets converted to ["this" "is" "arg1" "this" "is" "arg2"] in createOptions vector. Thus, val1 gets "this" and val2 gets "is" instead of "this is arg1" and "this is arg2" respectively.

How can I use boost::program_option to make this work ?

BЈовић
  • 62,405
  • 41
  • 173
  • 273
Onkar Deshpande
  • 301
  • 4
  • 15
  • 2
    The first thing to check is how the OS is providing those options to your program. If `cmdparsing.exe --create this is arg1` and `cmdparsing.exe --create "this is arg1"` result in the same contents for the `argv` array, then you have to find some other way of convincing your OS that the part in quotes needs to be kept together. – Bart van Ingen Schenau Nov 04 '10 at 13:43

2 Answers2

2

I fixed it using a native Windows function which handles command line arguments differently. See CommandLineToArgvW for details. Before passing it to processCommands(), I am modifying my argv[] and argc using the method mentioned above. Thank you Bart van Ingen Schenau for your comment.

#ifdef _WIN32
    argv = CommandLineToArgvW(GetCommandLineW(), &argc);
    if (NULL == argv)
    {
        std::wcout << L"CommandLineToArgvw failed" << std::endl;
        return -1;
    }
#endif
Onkar Deshpande
  • 301
  • 4
  • 15
0

You should be able to achieve this with positional options:

positional_options_description pos_desc;
pos_desc.add("create", 10); // Force a max of 10.

Then when you parse the command line add this pos_desc:

using namespace boost::program_options;
command_line_parser parser{argc, argv};
parser.options(desc).positional(pos_desc);
store(parser.run(), vm);
Fantastic Mr Fox
  • 32,495
  • 27
  • 95
  • 175