Книга: Основы программирования в Linux

getopt_long

getopt_long

Многие приложения Linux принимают более информативные аргументы, чем использованные в предыдущем примере односимвольные опции. Библиотека С проекта GNU содержит версию функции getopt, названную getopt_long, которая принимает так называемые длинные аргументы, которые вводятся с помощью двойного дефиса.

Рассмотрим упражнение 4.3.

Упражнение 4.3. Функция getopt_long

Примените функцию getopt_long для создания новой версии примера программы, которая может вызываться с использованием длинных эквивалентов опций, например, следующих:

$ ./longopt --initialize --list 'hi there' --file fred.c -q
option: i
option: l
filename: fred.c
./longopt: invalid option --q
unknown option: q
argument: hi there

На самом деле и новые длинные опции, и исходные односимвольные можно смешивать. Длинным опциям также можно давать сокращенные названия, но они

должны отличаться от односимвольных опций. Длинные опции с аргументом можно задавать как единый аргумент в виде --опция= значение, как показано далее:

$ ./longopt --init -l --file=fred.с 'hi there'
option: i
option: l
filename: fred.с
argument: hi there

Далее приведена новая программа longopt.c, полученная из программы argopt.c с изменениями, обеспечивающими поддержку длинных опций, которые в тексте программы выделены цветом.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define _GNU_SOURCE
#include <getopt.h>
int main(int argc, char *argv[]) {
 int opt;
 struct option_longopts[] = {
  {"initialize", 0. NULL, 'i'},
  {"file" 1, NULL, 'f'},
  {"list", 0, NULL, 'l'},
 {0, 0, 0, 0}};
 while ((opt = getopt_long(argc, argv, ":if:lr, longopts, NULL)) != -1) {
  switch(opt) {
  case 'i':
  case 'l':
  case 'r':
   printf("option: %cn", opt);
   break;
  case 'f':
   printf("filename: %sn", optarg);
   break;
  case ':':
   printf("option needs a valuen");
   break;
  case '?':
   printf("unknown option: %cn", optopt);
   break;
  }
 }
 for (; optind < argc; optind++)
  printf("argument: %sn", argv[optind]);
 exit(0);
}

Как это работает

Функция getopt_long принимает два дополнительных параметра по сравнению с функцией getopt. Первый из них — массив структур, описывающий длинные опции и сообщающий функции getopt_long способ их обработки. Второй дополнительный параметр — адрес переменной, которая может использоваться как вариант optind, предназначенный для длинных опций; для каждой распознанной длинной опции ее номер в массиве длинных опций может быть записан в эту переменную. В данном примере вам не нужна эта информация, поэтому вы используете NULL в качестве значения второго дополнительного параметра.

Массив длинных опций состоит из ряда структур типа struct option, в каждой из которых описано требуемое поведение длинной опции. Массив должен заканчиваться структурой, содержащей все нули.

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

struct option {
 const char *name;
 int has_arg;
 int *flag;
 int val;
};

Элементы структуры описаны в табл. 4.1.

Таблица 4.1.

Параметр опции Описание
name Название длинной опции. Сокращения будут приниматься до тех пор, пока они не создадут путаницы при определении названий других опций
has_arg Принимает ли эта опция аргумент. Задайте 0 для опций без аргументов, 1 для опций, у которых должно быть значение, и 2 для опций с необязательным аргументом
flag Задайте NULL, чтобы getopt_long вернула при обнаружении данной опции значение, заданное в val. В противном случае getopt_long возвращает 0 и записывает значение val в переменную, на которую указывает flag
val Значение getopt_long для данной опции, предназначенное для возврата

Для получения сведений о других опциях, связанных с расширениями функции getopt в проекте GNU и родственных функциях, см. страницы интерактивного справочного руководства к функции getopt.

Оглавление книги

Оглавление статьи/книги

Генерация: 0.628. Запросов К БД/Cache: 2 / 0
поделиться
Вверх Вниз