Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курс ПЯВУ 2 сем / Лекции 2 сем / Л№35.Аргументы кс / Лекция № 30.Аргументы командной строки..odt
Скачиваний:
12
Добавлен:
17.04.2015
Размер:
58.31 Кб
Скачать

10. Синтаксический анализ Длинных Опций

Чтобы воспринимать GNU стиль длинных опций также как одиночно символьные опции, используйте getopt_long вместо getopt. Вы должны заставить каждую программу принимать длинные опции, если она использует опции, это занимает немного ресурсов, и помогает новичкам помнить, как использовать программу.

struct option (тип данных)

Эта структура описывает одиночное длинное имя опции для getopt_long. Аргумент longopts должен быть массивом этих структур, по одной для каждой длинной опции.

Завершите массив элементом, содержащим все нули.

Структура option имеет поля:

const char *name

Это поле - имя опции. Это - строка.

int has_arg

Это поле говорит, берет ли опция аргумент. Это - целое число, и имеются три законных значения: no_argument, required_argument и optional_argument.

int *flag

int val

Эти поля управляют, как сообщать или действовать на опцию, когда она прочитана.

Если flag - пустой указатель, то val - значение, которое идентифицирует эту опцию. Часто эти значения выбраны, чтобы однозначно идентифицировать специфические длинные опции.

Если flag - не пустой указатель, это должен быть адрес int переменной, которая является флагом для этой опции. Значение в val - значение, которое нужно сохранить во флаге, чтобы указать, что опция была замечена.

int getopt_long (int argc, char **argv, const char *shortopts, struct option *longopts, int *indexptr) (функция)

Декодирует опции из вектора argv (чья длина argc). Аргумент shortopts описывает короткие опции, принимаемые точно так же как это делается в getopt. Аргумент longopts описывает длинные опции (см. выше).

Когда getopt_long сталкивается с короткой опцией, она делает ту же самую вещь, что и getopt: она возвращает символьный код для опции, и сохраняет аргумент этой опции (если он имеется) в optarg.

Когда getopt_long сталкивается с длинной опцией, она действует, основываясь на flag и val полях определения этой опции.

Если flag - пустой указатель, то getopt_long возвращает содержимое val, чтобы указать какую опцию она нашла. Вы должны указывать различные значения в val поле для опций с различными значениями, так что Вы можете декодировать эти значения после того, как getopt_long возвращается. Если длинная опция эквивалентна короткой опции, Вы может использовать код символа короткой опции в val.

Если flag - не пустой указатель, значит эта опция должна только установить флаг в программе. Флаг - переменная типа int, что Вы и определяете. Поместите адрес флага в поле flag. Поместите в val поле значение, которое Вы хотели бы, чтобы эта опция сохранила во флаге. В этом случае, getopt_long возвращает 0.

Для любой длинной опции, getopt_long сообщает Вам индекс в массиве longopts определения опций, сохраняя его в *indexptr. Вы можете получить имя опции через longopts [*indexptr].name . Так что Вы можете различать длинные опции или значениями в их val полях или их индексами.

Когда длинная опция имеет аргумент, getopt_long помещает значение аргумента в переменную optarg перед возвращением. Когда опция не имеет никакого аргумента, значение в optarg - пустой указатель.

Когда getopt_long не имеет больше опций для обработки, она возвращает -1, и оставляет в переменной optind индекс следующего остающегося аргумента в argv.

Пример Синтаксического анализа Длинных Опций

#include <stdio.h>

static int verbose_flag;

int

main (argc, argv)

int argc;

char **argv;

{

int c;

while (1)

{

static struct option long_options[] = {

{"verbose", 0, &verbose_flag, 1},

{"brief", 0, &verbose_flag, 0},

{"add", 1, 0, 0},

{"append", 0, 0, 0},

{"delete", 1, 0, 0},

{"create", 0, 0, 0},

{"file", 1, 0, 0},

{0, 0, 0, 0}

};

int option_index = 0;

c = getopt_long (argc, argv, "abc:d:",

long_options, &option_index);

if (c == -1)

break;

switch (c)

{

case 0:

if (long_options[option_index].flag

!= 0)

break;

printf ("option %s",

long_options[option_index].name);

if (optarg)

printf (" with arg %s", optarg);

printf ("\n");

break;

case 'a':

puts ("option -a\n");

break;

case 'b':

puts ("option -b\n");

break;

case 'c':

printf ("option -c with value

`%s'\n", optarg);

break;

case 'd':

printf ("option -d with value

`%s'\n", optarg);

break;

case '?':

/* getopt_long already printed an error message. */

break;

default:

abort ();

}

}

if (verbose_flag)

puts ("verbose flag is set");

/* Печатаем любые остающиеся аргументы командной строки

(не опции). */

if (optind < argc)

{

printf ("non-option ARGV-elements: ");

while (optind < argc)

printf ("%s ", argv[optind++]);

putchar ('\n');

}

exit (0);

}