Я пишу код для разбора ввода командной строки. Я использую getopt_long следующим образом:
int c = 0;
static struct option long_options[] =
{
{"mode", 1, NULL, 'm'},
{"help", 0, NULL, 'h'},
{0, 0, 0, 0}
};
while ((c = getopt_long(argc, argv, "mh", long_options, NULL))!=-1)
{
switch(c)
{
case 0:
{
cerr<<"Usage: ./program <-m> <-h>"<<endl;
exit(1);
break;
}
case 'm':
{
if (!strcmp(optarg, "small"))
mode = 0;
else if (!strcmp(optarg, "medium"))
mode = 1;
else if (!strcmp(optarg, "large"))
mode = 2;
else{
cerr<<"Invalid mode "<<optarg<<endl;
exit(1);
}
break;
}
case 'h':
{
cerr<<"See man page for help."<<endl;
exit(0);
}
default:
{
cerr<<"Unrecognized argument!"<<endl;
exit(1);
}
}
}
Я проверил следующее:
1)
./program
Программа не входит в цикл while. Переменная c проверяется на -1.
2)
./program -h
Работает хорошо.
3)
./program -m small
Выход из программы с сбросом ошибки сегментации из strcmp ().
Спасибо за любую помощь.
Вот пример, как разобрать параметры с getopt_long()
и правильно обрабатывать его возвращаемые значения, такие как конец параметров, отсутствующие аргументы и неизвестные параметры:
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);
}
};
Обратите внимание, что нет необходимости иметь соответствующую короткую опцию для каждой длинной опции.
Других решений пока нет …