I am trying to emulate something like this: apple --color red --count 5 orange --taste sour
Where I intend to make apple and orange as positional_option: subCommand and I intend to capture the remainder of options with values as unregistered options. Here is my sample code:
po::options_description desc("Supported options");
desc.add_options()
("subCom",po::value<string>(&sc),"")
;
po::positional_options_description pos;
pos.add("subCom",1);
po::variables_map vm;
po::parsed_options parsed =
po::command_line_parser(argc, argv).options(desc).positional(pos).allow_unregistered().run();
po::store(parsed, vm);
po::notify(vm);
Now when I actually run this: apple --color red --count 5
I am getting the error: too many positional options. program options is considering red as a positional option instead of treating it as a value for unregistered option. Could you please suggest a work around to this problem?
Try this (C++11, but if you wish you may to downgrade it easily)
#include <vector>
#include <string>
#include <boost/program_options.hpp>
namespace po = boost::program_options;
using namespace std;
int main(int argc, char* argv[]) {
po::options_description visibleOpts;
visibleOpts.add_options()
("help,h", "displays this help")
("verbose,v", po::value()->zero_tokens(), "increase debug level")
("silent,s", po::value()->zero_tokens(), "decrease debug level")
;
po::options_description hiddenOpts("");
vector files;
hiddenOpts.add_options()
("input-file", po::value >(&files)->required());
po::options_description opts;
opts.add(visibleOpts).add(hiddenOpts);
po::positional_options_description pos;
pos.add("input-file", -1);
// FIXME wrap this line with a proper try/catch
po::command_line_parser clp(argc, argv);
clp.options(visibleOpts).options(opts).positional(pos).allow_unregistered();
po::variables_map vm;
auto parsed = clp.run();
po::store(parsed, vm);
po::notify(vm);
if (vm.count("silent"))
cout << "silent was used" << endl;
if (vm.count("verbose"))
cout << "verbose was used" << endl;
{
vector unrecognized =
po::collect_unrecognized(parsed.options, po::exclude_positional);
if (!unrecognized.empty()) {
cout << "Got " << unrecognized.size() << " unrecognized option(s):" << endl;
for(auto uo: unrecognized)
cout << '\t' << uo << endl;
}
}
if (!files.empty()) {
cout << "Got " << files.size() << " file(s):" << endl;
for(auto f: files)
cout << '\t' << f << endl;
}
return 0;
}
it gives me the following output:
alex@galene c++/tests/build $ ./boost_po_pos --silent --boo abcde ssss silent was used Got 1 unrecognized option(s): --boo Got 2 file(s): abcde ssss alex@galene c++/tests/build $