Linux программирование в примерах - страница 22
Во-первых, записав 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 используются имена в виде >xflg
для любого данного символа опции x (например, >nflg
в >echo
V7; обычным является также >xflag
). Это может быть замечательным для авторе программы, который без проверки документации знает, что означает опция x. Но это не подходит для кого-то еще, кто пытается прочесть код и не знает наизусть значений всех символов опций. Гораздо лучше использовать имена, передающие смысл опции, как >no_newline
для опции >-n
echo.
2.3.2. GNU >getopt()
и порядок опций
Стандартная функция >getopt()
прекращает поиск опций, как только встречает аргумент командной строки, который не начинается с GNU >getopt()
отличается: она просматривает в поисках опций всю командную строку. По мере продвижения она переставляет элементы >argv
, так что после ее завершения все опции оказываются переставленными в начало, и код, продолжающий разбирать аргументы с >argv[optind]
до >argv[argc-1]
, работает правильно. Во всех случаях специальный аргумент '>--
' завершает сканирование опций.
Вы можете изменить поведение по умолчанию, использовав в >optstring
специальный первый символ следующим образом:
>optstring[0] == '+'
GNU >getopt()
ведет себя, как стандартная >getopt()
; она возвращает опции по мере их обнаружения, останавливаясь на первом аргументе, не являющемся опцией. Это работает также в том случае, если в окружении присутствует строка >POSIXLY_CORRECT
.
>optstring[0] == '-'
GNU >getopt()
возвращает каждый аргумент командной строки независимо от того, представляет он аргумент или нет. В этом случае для каждого такого аргумента функция возвращает целое 1, а указатель на соответствующую строку помещает в >optarg
.
Как и для стандартной >getopt()
, если первым символом >optstring
является '>:
', GNU >getopt()
различает «неверную опцию» и «отсутствующий аргумент опции», возвращая соответственно '>?
' или '>:
'. Символ '>:
' в >optstring
может быть вторым символом, если первым символом является '>+
' или '>-
'.
Наконец, если за символом опции в >optstring
следуют два двоеточия, эта опция может иметь необязательный аргумент. (Быстро повторите это три раза!) Такой аргумент считается присутствующим, если он находится в том же элементе >argv
, что и сама опция, и отсутствующим в противном случае. В случае отсутствия аргумента GNU >getopt()
возвращает символ опции, а в >optarg
записывает NULL. Например, пусть имеем:
>while ((с = getopt(argc, argv, "ab::")) != -1)
>...
для >-bYANKEES
, возвращаемое значение будет '