boost::program_options - parsing multiple command line arguments where some are strings including spaces and characters
Asked Answered
M

2

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 ?

Motorboating answered 3/11, 2010 at 22:58 Comment(1)
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.Epigrammatize
M
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
Motorboating answered 4/11, 2010 at 20:57 Comment(0)
L
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);
Lippe answered 14/12, 2017 at 5:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.