How to handle unsolicited parameters in boost::program_options

boost, boost-program-options, c++

Solution

I came up with code that does the trick, but it is a slight workaround. That is, I dropped the positional clause and resorted to taking the first argument of the unrecognized ones. It seems to be working fine, but it is not very flexible.

using namespace boost::program_options;

options_description desc("Allowed options");
desc.add_options()
    ("help,h", "produce help message")
    ("version,v", "print the version number")
    ("include-path,I", value< vector<string> >(), "include path")
    ("input-file,i", value<string>(), "input file")
    ;

variables_map vm;
vector<string> additionalParameters;

parsed_options parsed = command_line_parser(ac, av).
    options(desc).allow_unregistered().run();
store(parsed, vm);
additionalParameters = collect_unrecognized(parsed.options, 
    include_positional);
notify(vm);

if (!vm.count("input-file"))
    if (additionalParameters.empty()) 
    {
        cerr << "error: No input file specified\n";
        return EXIT_FAILURE;
    } 
    else
    {
        inputFileName = additionalParameters[0];
        additionalParameters.erase(additionalParameters.begin());
    }
else
    inputFileName = vm["input-file"].as<string>();

Problem

I use `boost::program_options` to provide command line parsing interface to my application. I would like to configure it to parse the options, ``` using namespace boost::program_options; options_description desc("Allowed options"); desc.add_options() ("help,h", "produce help message") ("version,v", "print the version number") ("include-path,I", value< vector<string> >(), "include path") ("input-file,i", value<string>(), "input file"); positional_options_description p; p.add("input-file", 1); variables_map vm; parsed_options parsed = command_line_parser(ac, av). options(desc).positional(p).run(); store(parsed, vm); notify(vm); ``` I would like to configure it so that every token after the last switch is returned in a form of vector. I have tried using `collect_unrecognized` as per example given in Boost documentation but I have ran into some problems because I am also using positional arguments for the input file. Basically I would like to do it like this. If I have: ``` ./program -i "inputfile.abc" argument1 argument2 argument3 ``` I would like it to store `inputfile.abc` in the `input-file` value and return a `vector<string>` of `argument1`, `argument2` and `argument3` as unsolicited arguments. I would however also like to be able to have a positional argument, so that ``` ./program "inputfile.abc" argument1 argument2 argument3 ``` would give me the same result. I am sorry if this has already been asked and thank you for help.

Original source