Вы можете изменить поведение по умолчанию, использовав в
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
, возвращаемое значение будет '
b
', a
optarg
указывает на «
YANKEES
», тогда как для
-b
или '
-b YANKEES
' возвращаемое значение будет все то же '
b
', но в
optarg
будет помещен NULL. В последнем случае «
YANKEES
» представляет отдельный аргумент командной строки.
2.3.3. Длинные опции
Функция
getopt_long()
осуществляет разбор длинных опций в описанном ранее виде. Дополнительная процедура
getopt_long_only()
работает идентичным образом, но она используется для программ, в которых все опции являются длинными и начинаются с единичного символа '
-
'. В остальных случаях обе функции работают точно так же, как более простая функция GNU
getopt()
. (Для краткости, везде, где мы говорим «
getopt_long()
», можно было бы сказать «
getopt_long()
и
getopt_long_only()
».) Вот объявления функций из справки getopt(3) GNU/Linux:
#include <getopt.h> /* GLIBC */
int getopt_long(int argc, char *const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char *const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
Первые три аргумента те же, что и в
getopt()
. Следующая опция является указателем на массив
struct option
, который мы назовем
таблицей длинных опций и который вскоре опишем. Параметр
longindex
, если он не установлен в NULL, указывает на переменную, в которую помешается индекс обнаруженной длинной опции в
longopts
. Это полезно, например, при диагностике ошибок.
2.3.3.1. Таблица длинных опций
Длинные опции описываются с помощью массива структур
struct option
. Структура
struct option
определена в
<getopt.h>
; она выглядит следующим образом:
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
Элементы структуры следующие:
const char *name
Это имя опции без предшествующих черточек, например, «
help
» или «
verbose
».
int has_arg
Переменная описывает, имеет ли длинная опция аргумент, и если да, какого вида этот аргумент. Значение должно быть одно из представленных в табл. 2.1. Макроподстановки являются некоторыми символическими именами для числовых значений, приведенных в таблице. Хотя числовые значения тоже работают, макроподстановки гораздо легче читать, и вы должны их использовать вместо соответствующих чисел в любом коде, который пишете.
int *flag
Если этот указатель равен NULL,
getopt_long()
возвращает значение поля
val
структуры. Если он не равен NULL, переменная, на которую он указывает, заполняется значением
val
, a
getopt_long()
возвращает 0. Если
flag
не равен NULL, но длинная опция отсутствует, указанная переменная не изменяется.
int val
Если длинная опция обнаружена, это возвращаемое значение или значение для загрузки в
*flag
, если
flag
не равен NULL. Обычно, если
flag
не равен NULL,
val
является значением true/false, вроде 1 или 0. С другой стороны, если
flag
равен NULL,
val
обычно содержит некоторую символьную константу. Если длинная опция соответствует короткой, эта символьная константа должна быть той же самой, которая появляется в аргументе
optstring
для этой опции. (Все это станет вскоре ясно, когда мы рассмотрим несколько примеров.)