Linux программирование в примерах | страница 38
>val
обычно содержит некоторую символьную константу. Если длинная опция соответствует короткой, эта символьная константа должна быть той же самой, которая появляется в аргументе >optstring
для этой опции. (Все это станет вскоре ясно, когда мы рассмотрим несколько примеров.)Таблица 2.1. Значения для >has_arg
Макроподстановка | Числовое значение | Смысл |
---|---|---|
>no_argument | 0 | Опция не принимает аргумент |
>required_argument | 1 | Опции требуется аргумент |
>optional_argument | 2 | Аргумент опции является необязательным |
У каждой длинной опции есть один такой элемент с соответствующими заполненными значениями. В последнем элементе массива все значения должны быть равны нулю. Нет необходимости сортировать массив: >getopt_long()
осуществляет линейный поиск. Однако, сортировка его по длинным именам может упростить его чтение для программиста.
При первой встрече использование >flag
и >val
кажется сбивающим с толку. Давайте сделаем на время шаг назад и рассмотрим, почему это работает именно таким способом В большинстве случаев, обработка опций заключается в установке значений различных флаговых переменных при обнаружении различных символов опций, наподобие этого:
>while ((с = getopt(argc, argv, ":af:hv")) != -1) {
> switch (с) {
> case 'a':
> do_all = 1;
> break;
> case 'f':
> myfile = optarg;
> break;
> case 'h':
> do_help = 1;
> break;
> case 'v':
> do_verbose = 1;
> break;
> ... /* Здесь обработка ошибок */
> }
>}
Когда >flag
не равен NULL, >getopt_long()
устанавливает значения переменных за вас. Это снижает число операторов >case
в предыдущем >switch
с трех до одного. Вот пример таблицы длинных опций и код для работы с ней:
>int do_all, do_help, do_verbose; /* флаговые переменные */
>char *my_file;
>struct option longopts[] = {
> { "all", no_argument, &do_all, 1 },
> { "file", required_argument, NULL, 'f' },
> { "help", no_argument, &do_help, 1 },
> { "verbose", no_argument, &do_verbose, 1 },
> { 0, 0, 0, 0 }
>};
>while ((с =
> getopt_long(argc, argv, ":f:", longopts, NULL)) != -1) {
> switch (c) {
> case 'f':
> myfile = optarg;
> break;
> case 0:
> /* getopt_long() устанавливает значение переменной,
> просто продолжить выполнение */
> break;
> ... /* Здесь обработка ошибок */
> }
>}
Обратите внимание, что значение, переданное аргументу >optstring
, не содержит больше '>a
', '>h
' или '>v
'. Это означает, что соответствующие короткие опции неприемлемы. Чтобы разрешить как длинные, так и короткие опции, вам придется восстановить в >switch
соответствующие >case
из первого примера.