I'm trying to use long_options[] to parse different options entered from the terminal to a C++ program. My options struct looks like:
static struct option long_options[] = {
// *name, has_arg, *flag, val
{"help", no_argument, 0, 'h'},
{"debug", no_argument, 0, 0},
{"seed", required_argument, 0, 's'},
...
}
Then I'd use getopt_long to read the arguments as follows:
while (true) {
int option_index (0);
int c = getopt_long (argc, argv, "hs:t:iT:N:M:m:V:l:w:P:rR:b:d:a:", long_options, &option_index);
if (c == -1) break;
switch (c) {
case 'h':
print_help ();
case 's':
parameters.seed = atoi(optarg);
break;
case 0:
if (long_options[option_index].flag != 0) break;
else if (strcmp(long_options[option_index].name, "debug") == 0) parameters.debug = true;
...
break;
}
}
The arguments are passed to optarg, which I understand is of type char* or std::string, as shown above.
The problem comes when I think of a way to set an option parameters with a required number of two or more arguments. For instance, I would like to set an option that allows the user to define distribution parameters conveniently. I'd hope this to be called from the terminal as follows:
./program --distribution mean sd
./program --distribution mean sd n
But it seems that long_options expects just one argument by option by default, so sd in the example above is expected to be parsed as a separate option parameter.
How can I change this default behavior? thank you!
You can't, and it is not conventional to do so.
To give your application an unorthodox command-line arguments structure, you'll have to write your own parser.
A workaround would be to require your users to send their multiple words in one parameter:
./program --distribution 'mean sd n'
though you'd still need to parse this resulting multi-word string yourself.
Boost.ProgramOptions is a little more flexible than old getopt
, without deviating too much from accepted "standard" practice for command-line arguments, but determining whether it does what you want will require research.