Linux программирование в примерах
Для использования
вызывайте ее повторно из циклаgetopt()до тех пор, пока она не вернетwhile. Каждый раз, обнаружив действительный символ опции, функция возвращает этот символ. Если опция принимает аргумент, указатель на него помещается в переменную-1. Рассмотрим программу, принимающую опциюoptargбез аргумента и опцию-ас аргументом:-bint ос; /* символ опции */char *b_opt_arg;while ((ос = getopt(argc, argv, "ab:")) != -1) {switch (oc) {case 'a':/* обработка -а, установить соответствующий флаг */break;case 'b':/* обработка -b, получить значение аргумента из optarg */b_opt_arg = optarg;break;case ':':... /* обработка ошибок, см. текст */case '?':default:... /* обработка ошибок, см. текст */}}В ходе работы
устанавливает несколько переменных, контролирующих обработку ошибок:getopt()char *optargАргумент для опции, если она принимает аргумент.
int optindТекущий индекс в
. Когда циклargvзавершается, оставшиеся операнды находятся сloopпоargv[optind]. (Помните, что 'argv[argc-1]'.)argv [argc] ==NULLint opterrКогда эта переменная не равна нулю (значение по умолчанию),
печатает свои собственные сообщения для недействительных опций или отсутствующих аргументов опций.getopt()int optoptКогда находится недействительный символ опции,
возвращает либо 'getopt()', либо '?' (см ниже), a:содержит обнаруженный недействительный символ.optoptЛюди есть люди, программы неизбежно будут иногда вызываться неправильно либо с недействительной опцией, либо с отсутствующим аргументом опции. Обычно в таких случаях
выводит свои собственные сообщения и возвращает символ 'getopt()'. Однако, вы можете изменить такое поведение двумя способами.?Во-первых, записав 0 в
перед вызовомopterr, можно заставитьgetopt()не предпринимать при обнаружении проблем никаких действий.getopt()Во-вторых, если первый символ в
является двоеточием,optstringне предпринимает никаких действий и возвращает другой символ в зависимости от ошибки следующим образом:getopt()Неверная опция
возвращает 'getopt()', a?содержит неверный символ опции (Это обычное поведение).optoptОтсутствует аргумент опции
возвращает 'getopt()'. Если первый символ:не является двоеточием,optstringвозвращает 'getopt()', делая этот случай неотличимым от случая неверной опции.?Таким образом, помещение в качестве первого символа
двоеточия является хорошей мыслью, поскольку это позволяет различать «неверную опцию» и «отсутствующий аргумент опции». Расплатой за это является то, чтоoptstringв этом случае также не предпринимает никаких действий, заставляя вас выводить собственные сообщения об ошибках. Вот предыдущий пример, на этот раз с обработкой ошибок:getopt()int ос; /* символ опции */char *b_opt_arg;while ((ос = getopt(argc, argv, ":ab:")) != -1) {switch (oc) {case 'a':/* обработка -a, установка соответствующего флага */break;case 'b':/* обработка -b, получение значения аргумента из optarg */b_opt_arg = optarg;break;case ':':/* отсутствует аргумент опции */fprintf(stderr, "%s: option '-%c' requires an argument\n",argv[0], optopt);break;case '?':default:/* недействительная опция */fprintf(stderr, "%s: option '-%c' is invalid: ignored\n",argv[0], optopt);break;}}Замечание о соглашениях по именованию флагов или опций: в большом количестве кода для Unix используются имена в виде
для любого данного символа опции x (например,xflgвnflgV7; обычным является такжеecho). Это может быть замечательным для авторе программы, который без проверки документации знает, что означает опция x. Но это не подходит для кого-то еще, кто пытается прочесть код и не знает наизусть значений всех символов опций. Гораздо лучше использовать имена, передающие смысл опции, какxflagдля опцииno_newlineecho.-n2.3.2. GNU
и порядок опцийgetopt()Стандартная функция
прекращает поиск опций, как только встречает аргумент командной строки, который не начинается с GNUgetopt()отличается: она просматривает в поисках опций всю командную строку. По мере продвижения она переставляет элементыgetopt(), так что после ее завершения все опции оказываются переставленными в начало, и код, продолжающий разбирать аргументы сargvдоargv[optind], работает правильно. Во всех случаях специальный аргумент 'argv[argc-1]' завершает сканирование опций.--