KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Марк Митчелл - Программирование для Linux. Профессиональный подход

Марк Митчелл - Программирование для Linux. Профессиональный подход

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Марк Митчелл, "Программирование для Linux. Профессиональный подход" бесплатно, без регистрации.
Перейти на страницу:

Опции бывают двух видов.

■ Короткие опции состоят из дефиса и одиночного символа (обычно это буква в нижнем или верхнем регистре). Такие опции быстрее и проще набирать.

■ Длинные опции состоят из двух дефисов, после которых следует имя. содержащее буквы нижнего и верхнего регистров и дефисы. Такие опции легче запоминать и читать (например, в командных сценариях).

Обычно программа поддерживает обе разновидности каждой опции: первую — для краткости, вторую — для ясности. Например, большинство программ понимает опции -h и --help и трактует их одинаково. Как правило, опции указываются сразу после имени программы. После опций могут идти другие аргументы, в частности имена входных файлов и входные данные.

Некоторые опции предполагают наличие собственных аргументов. Так, рассмотренная выше команда ls -s / выводит содержимое корневого каталога. Опция -s сообщает программе ls о необходимости отображения размера (в килобайтах) каждого элемента каталога. Аргумент / задает имя каталога. Опция --size является синонимом опции -s, поэтому та же самая команда может быть задана так: ls -- size /.

В документе GNU Coding Standards перечислены имена некоторых наиболее часто используемых опций командной строки. При написании GNU-программ рекомендуется сверяться с этим документом. Пользователям удобно работать с программами, у которых много общих черт. Получить доступ к упомянутому документу в большинстве Linux-систем позволяет команда

% info "(standards)User Interfaces"

2.1.3. Функция getopt_long()

Синтаксический анализ аргументов командной строки — утомительная задача. К счастью. в GNU-библиотеке языка С есть функция getopt_long(), упрощающая ее решение. Эта функция понимает как короткие, так и длинные опции. Ее объявление находится в файле <getopt.h>.

Предположим, требуется написать программу, которая поддерживает три опции (табл. 2.1).


Таблица 2.1. Опции тестовой программы

Короткая форма Длинная форма Назначение -h --help Отображение справки по использованию программы и выход -o имя_файла --output имя_файла Задание имени выходного файла -v --verbose Отображение развернутых сообщений

Кроме того, программе могут быть переданы дополнительные аргументы, задающие имена входных файлов

Функции getopt_long() нужно передать две структуры. Первая — это строка с описанием возможных коротких опций (каждая из них представлена одной буквой). Если опция предполагает наличие аргумента, после нее ставится двоеточие. В нашем случае строка будет иметь вид ho:v. Это говорит о том, что программа поддерживает опции -h, -о и -v, причем для второй из них требуется аргумент.

Список возможных длинных опций задается в виде массива структур option. Каждый элемент массива соответствует одной опции и состоит из четырех полей. Чаще всего первое поле содержит имя опции (строка символов без ведущих дефисов), второе  — 1, если опция принимает аргумент, и 0 — в противном случае: третье — NULL; четвертое — символьная константа, задающая короткий эквивалент данной длинной опции. Последний элемент массива должен содержать одни нули. Наш массив будет выглядеть так:

const struct option long_options[] = {

 { "help",    0, NULL, 'h' },

 { "output",  1, NULL, 'o' },

 { "verbose", 0, NULL, 'v' },

 { NULL,      0, NULL, 0 }

};

Функции getopt_long() передаются также параметры argc и argv функции main(). Ниже перечислены особенности ее работы.

■ При каждом вызове функция getopt_long() анализирует очередную опцию, возвращая букву, которая соответствует короткому эквиваленту опции. При отсутствии опций возвращается -1.

■ Обычно функция getopt_long() вызывается в цикле для обработки всех опций командной строки. Выбор конкретной опции осуществляется посредством конструкции switch.

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

■ При обработке опции, имеющей аргумент, в глобальную переменную optarg помещается указатель на строку с содержимым аргумента.

■ Когда функция getopt_long() завершает анализ опций, в глобальную переменную optind записывается индекс того элемента массива argv, в котором содержится первый аргумент, не являющийся опцией.

В листинге 2.2 приведен пример обработки аргументов программы с помощью функции getopt_long().

Листинг 2.2. (getopt_long.c) Использование функции getopt_long()

#include <getopt.h>

#include <stdio.h>

#include <stdlib.h>


/* Имя программы. */

const char* program_name;


/* Вывод информации об использовании программы в поток STREAM

   (обычно stdout или stderr) и завершение работы с выдачей кода

   EXIT_CODE. Возврат в функцию main() не происходит */

void print_usage(FILE* stream, int exit_code) {

 fprintf(stream, "Usage: %s options [ inputfile ... ]n",

  program_name);

 fprintf(stream,

  " -h --help    Display this usage

                 information.n"

  " -о --output  filename Write output to file.n"

  " -v --verbose Print verbose messages.n");

 exit(exit_code);

}


/* Точка входа в основную программу, параметр ARGC содержит размер

   списка аргументов; параметр ARGV -- это массив указателей

   на аргументы. */

int main(int argc, char* argv[]) (

 int next_option;


 /* Строка с описанием возможных коротких опций. */

 const char* const short_options = "ho:v";

 /* Массив с описанием возможных длинных опций. */

 const struct option long_options[] = {

  { "help",    0, NULL, 'h' },

  { "output",  1, NULL, 'o' },

  { "verbose", 0, NULL, 'v' },

  { NULL,      0, NULL, 0 } /* Требуется в конце массива. */

 };


 /* Имя файла, в который записываются результаты работы

    программы, или NULL, если вывод направляется в поток

    stdout. */

 const char* output_filename = NULL;

 /* Следует ли выводить развернутые сообщения. */

 int verbose = 0;


 /* Запоминаем имя программы, которое будет включаться

    в сообщения. Оно хранится в элементе argv[0] */

 program_name = argv[0];


 do {

  next_option =

   getopt_long(argc, argv, short_options,

    long_options, NULL);

  switch(next_opt ion) {

  case "h": /* -h или --help */

   /* Пользователь запросил информацию об использовании

      программы, нужно вывести ее в поток stdout и завершить

      работу с выдачей кода 0 (нормальное завершение). */

   print_usage(stdout, 0);

  case 'o': /* -о или --output */

   /* Эта опция принимает аргумент -- имя выходного файла. */

      output_filename = optarg;

   break;

  case 'v': /* -v или --verbose */

   verbose = 1;

   break;

  case '?': /* Пользователь ввел неверную опцию. */

   /* Записываем информацию об использовании программы в поток

      stderr и завершаем работу с выдачей кода 1

      (аварийное завершение). */

   print_usage(stderr, 1);

  case -1: /* Опций больше нет. */

   break;

  default: /* Какой-то непредвиденный результат. */

   abort();

  }

 }

 while (next_option != -1);


 /* Обработка опций завершена, переменная OPTIND указывает на

    первый аргумент, не являющийся опцией. В демонстрационных

    целях отображаем эти аргументы, если задан режим VERBOSE. */

 if (verbose) {

  int i;

  for (i = optind; i < argc; ++i)

   printf("Argument: %sn", argv[i]);

 }


 /* Далее идет основное тело программы... */


 return 0;

}

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*