Linux программирование в примерах - Страница 13

Изменить размер шрифта:

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 изображена эта ситуация.

Linux программирование в примерах - img_2.png

Рис. 2.2. Память для

argc

По соглашению,

argv[0]
является именем программы. (Детали см. в разделе 9.1.4.3. «Имена программ и
argv[0]
».) Последующие элементы являются аргументами командной строки. Последним элементом массива
argv
является указатель
NULL
.

argc
указывает, сколько имеется аргументов; поскольку в С индексы отсчитываются с нуля, выражение '
argv[argc] == NULL
' всегда верно. Из-за этого, особенно в коде для Unix, вы увидите различные способы проверки окончания списка аргументов, такие, как цикл с проверкой, что счетчик превысил
argc
, или '
argv[i] == 0
', или '
*argv != NULL
' и т.д. Они все эквивалентны.

2.2.1. Программа

echo
V7

Возможно, простейшим примером обработки командной строки является программа V7

echo,
печатающая свои аргументы в стандартный вывод, разделяя их пробелами и завершая символом конца строки. Если первым аргументом является
-n
, завершающий символ новой строки опускается. (Это используется для приглашений из сценариев оболочки.) Вот код[28]:

1  #include <stdio.h>

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<argc; 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()
не была еще придумана.

Наконец, здесь и в других местах по всей книге, мы видим использование ключевого слова register. Одно время это ключевое слово давало компилятору подсказку, что данная переменная должна по возможности размещаться в регистре процессора. Теперь это ключевое слово устарело; современные компиляторы все основывают размещение переменных в регистрах на анализе исходного кода, игнорируя ключевое слово

register
. Мы решили оставить использующий это слово код, как есть, но вы должны знать, что оно больше не имеет реального применения.[29]

2.3. Разбор опций:

getopt()
и
getopt_long()

Примерно в 1980-х группа поддержки Unix для System III в AT&T заметила, что каждая программа Unix использовала для разбора аргументов свои собственные методики. Чтобы облегчить работу пользователей и программистов, они разработали большинство из перечисленных ранее соглашений. (Хотя изложение в System III справки для intro(1) значительно менее формально, чем в стандарте POSIX.)

Группа поддержки Unix разработала также функцию

getopt()
, вместе с несколькими внешними переменными, чтобы упростить написание кода, придерживающегося стандартных соглашений. Функция GNU
getopt_long()
предоставляет совместимую с
getopt()
версию, а также упрощает разбор длинных опций в описанной ранее форме.

2.3.1. Опции с одним символом

Функция

getopt()
объявлена следующим образом:

#include <unistd.h> /*POSIX*/

int getopt(int argc, char *const argv[], const char *optstring);

extern char *optarg;

extern int optind, opterr, optopt;

Аргументы

argc
и
argv
обычно передаются непосредственно от
main()
.
optstring
является строкой символов опций. Если за какой-либо буквой в строке следует двоеточие, эта опция ожидает наличия аргумента.

Оригинальный текст книги читать онлайн бесплатно в онлайн-библиотеке Knigger.com