getopt_long действует странно

Я пишу код для разбора ввода командной строки. Я использую 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 ().

Спасибо за любую помощь.

0

Решение

Вот пример, как разобрать параметры с 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);
}
};

Обратите внимание, что нет необходимости иметь соответствующую короткую опцию для каждой длинной опции.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]