1. У программ, реализующих инструменты POSIX, каждая короткая опция (один символ) должна иметь также свой вариант в виде длинной опции.
2. Дополнительные специфические для GNU опции не нуждаются в соответствующей короткой опции, но мы рекомендуем это сделать.
3. Длинную опцию можно сократить до кратчайшей строки, которая остается уникальной. Например, если есть две опции --verbose
и --verbatim
, самыми короткими сокращениями будут --verbo
и --verba
.
4. Аргументы опции отделяются от длинных опций либо разделителем, либо символом =
. Например, --sourcefile=/some/file
или --sourcefile /some/file
.
5. Опции и аргументы могут быть заинтересованы в операндах командной строки, getopt_long()
переставляет аргументы таким образом, что сначала обрабатываются все опции, а затем все операнды доступны последовательно. (Такое поведение можно запретить.)
6. Аргументы опций могут быть необязательными. Для таких опций считается, что аргумент присутствует, если он находится в одной строке с опцией. Это работает лишь для коротких опций. Например, если -х такая опция и дана строка ' foo -хYANKEES -y
', аргументом -х
является ' YANKEES
'. Для ' foo -х -y
' у -х
нет аргументов.
7. Программы могут разрешить длинным опциям начинаться с одной черточки (Это типично для многих программ X Window.)
Многое из этого станет яснее, когда позже в этой главе мы рассмотрим getopt_long()
.
GNU Coding Standards уделяет значительное место перечислению всех длинных и коротких опций, используемых программами GNU. Если вы пишете программу, использующую длинные опции, посмотрите, нет ли уже использующихся имен опций, которые имело бы смысл использовать и вам.
2.2. Базовая обработка командной строки
Программа на С получает доступ к своим аргументам командной строки через параметры argc
и argv
. Параметр argc
является целым, указывающим число имеющихся аргументов, включая имя команды. Есть два обычных способа определения main()
, отличающихся способом объявления argc
:
int main(int argc, char *argv[]) int main(int argc, char **argv)
{ {
... ...
} }
Практически между двумя этими объявлениями нет разницы, хотя первое концептуально более понятно: argc
является массивом указателей на символы. А второе определение технически более корректно, это то, что мы используем. На рис. 2.2 изображена эта ситуация.
Рис. 2.2. Память для argc
По соглашению, argv[0]
является именем программы. (Детали см. в разделе 9.1.4.3. «Имена программ и argv[0]
».) Последующие элементы являются аргументами командной строки. Последним элементом массива argv
является указатель NULL
.
argc
указывает, сколько имеется аргументов; поскольку в С индексы отсчитываются с нуля, выражение ' argv[argc] == NULL
' всегда верно. Из-за этого, особенно в коде для Unix, вы увидите различные способы проверки окончания списка аргументов, такие, как цикл с проверкой, что счетчик превысил argc
, или ' argv[i] == 0
', или ' *argv != NULL
' и т.д. Они все эквивалентны.
Возможно, простейшим примером обработки командной строки является программа V7 echo,
печатающая свои аргументы в стандартный вывод, разделяя их пробелами и завершая символом конца строки. Если первым аргументом является -n
, завершающий символ новой строки опускается. (Это используется для приглашений из сценариев оболочки.) Вот код [28] См. /usr/src/cmd/echo.c в дистрибутиве V7 — Примеч. автора .
:
1 #include
2
3 main(argc, argv) /*int main(int argc, char **argv)*/
4 int argc;
5 char *argv[];
6 {
7 register int i, nflg;
8
9 nflg = 0;
10 if (argc > 1 && argv[1][0] == && argv[1][1] == 'n') {
11 nflg++;
12 argc--;
13 argv++;
14 }
15 for (i=1; i
16 fputs(argv[i], stdout);
17 if (i < argc-1)
18 putchar(' ');
19 }
20 if (nflg == 0)
21 putchar('\n');
22 exit(0);
23 }
Всего 23 строки! Здесь есть два интересных момента. Во-первых, уменьшение argc
и одновременное увеличение argv
(строки 12 и 13) являются обычным способом пропуска начальных аргументов. Во-вторых, проверка наличия -n
(строка 10) является упрощением. -no-newline-at-the-end
также работает. (Откомпилируйте и проверьте это!)
Ручной разбор опций обычен для кода V7, поскольку функция getopt()
не была еще придумана.
Читать дальше