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, возвращаемое значение будет '