Here is an example how to parse options with getopt_long()
and correctly handle its return values, such as end of options, missing arguments and unknown options:
struct Options
{
std::string username = "guest";
void parse_command_line(int ac, char** av) try {
enum {
HELP
, USER
};
// This array must be in the same order as the enum.
option const options[] = {
{"help", no_argument, nullptr, HELP}
, {"username", required_argument, nullptr, USER}
, {}
};
::opterr = 0;
for(int c; -1 != (c = getopt_long(ac, av, ":h", options, nullptr));) {
switch(c) {
// both short and long option
case 'h':
case HELP:
usage(av, EXIT_SUCCESS);
break;
// only long option
case USER:
username = ::optarg; //
break;
case ':': // missing argument
throw Exception("--%s: an argument required", options[::optopt].name);
case '?': // unknown option
throw Exception("%s: unknown option", av[optind - 1]);
}
}
}
catch(std::exception& e) {
fprintf(stderr, "error: %s\n", e.what());
usage(av, EXIT_FAILURE);
}
};
Note, that it is not necessary to have a corresponding short option for each long option.