#include <unistd.h> int getopt(int argc, char * const argv[], const char *optstring); extern char *optarg; extern int optind, opterr, optopt; #define _GNU_SOURCE
#include <getopt.h> int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex); int getopt_long_only(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);
Если getopt() находит символ опции, она возвращает этот символ, обновляя внешнюю переменную optind и статическую переменную nextchar, так что следующий вызов getopt() может продолжить проверку со следующего символа опции или элемента argv.
Если символов опций больше нет, то getopt() возвращает -1. При этом optind станет индексом первого элемента argv, не являющегося опцией.
optstring является строкой, содержащей допустимые символы опций. Если за таким символом стоит двоеточие, то опция требует указания аргумента. При этом getopt() помещает указатель на следующий за символом опции текст, в тот же элемент argv, или на текст следующего элемента argv, в optarg. Два двоеточия означают, что опция имеет необязательный аргумент; если текущий элемент argv содержит текст, то он возвращается в optarg, в противном случае optarg содержит ноль. Это является дополнением GNU. Если optstring содержит W, за которой следует точка с запятой, то -W foo рассматривается как длинная опция --foo. Опция -W зарезервирована POSIX.2 для реализации расширений. Такое поведение является дополнительным для GNU и недоступным в библиотеках GNU libc более ранних по сравнению со второй версий.
По умолчанию getopt() переставляет элементы содержимого argv в процессе поиска, так что в конечном счете все аргументы, не являющиеся опциями, оказываются в конце. Реализованы также два других режима. Если первым символом optstring является "+" или задана переменная окружения POSIXLY_CORRECT, то обработка опций прерывается на первом аргументе, не являющемся опцией. Если первым символом optstring является "-", то каждый элемент argv, не являющийся опцией, обрабатывается так, как если бы он был аргументом опции с символом, имеющим код 1. Она используется программами, которые требуют опции и другие аргументы командной строки. Специальный аргумент "--" служит для обозначения конца опций независимо от режима.
Если getopt() не распознал символ опции, то он выводит на стандартный поток ошибок соответствующее сообщение, заносит символ в optopt и возвращает "?". Вызывающая программа может предотвратить вывод сообщения об ошибке, установив нулевое значение opterr.
Если функция getopt() обнаружит в argv символ опции, не найденный в optstring, или если она обнаружит пропущенный аргумент опции, то она возвратит `?' и занесет во внешную переменную optopt действительный символ опции. Если первым символом optstring является двоеточие (`:'), то для сообщения о пропущенном аргументе опции getopt() возвратит `:' вместо `?'. Если при обнаружении ошибки первый символ optstring не является двоеточием и внешняя переменная opterr не равно нулю (по умолчанию так и есть), то getopt() выведет сообщение об ошибке.
Функция getopt_long() работает так же, как getopt(), за исключением того, что она воспринимает и длинные опции, начинающиеся с двух дефисов. Длинные опции можно сокращать, если сокращение сохраняет уникальность опции или полностью совпадает с одной из определенных опций. Длинная опция может иметь параметр вида --опция=параметр или --опция параметр.
longopts является указателем на первый элемент массива структур struct option, указанного в <getopt.h> следующим образом
struct option { const char *name; int has_arg; int *flag; int val; };
Значения различных полей:
Последний элемент массива должен быть заполнен нулями.
Если longindex не содержит NULL, то он является указателем на переменную, содержащую индекс длинной опции в соответствии с longopts.
getopt_long_only() работает так же, как getopt_long(), но в качестве указателя длинной опции может служить не только "--", но и "-". Если опция, начинающаяся с "-" (не с "--"), не совпадает с длинной опцией, но совпадает с короткой, то она обрабатывается как короткая опция.
getopt_long() и getopt_long_only() также возвращают символ опции, если распознана короткая опция. Для длинной опции они возвращают val, если flag равен NULL, и 0 в остальных случаях. Возвращаемые ошибки и -1 имеют то же значение, что и для getopt(), кроме того, "?" возвращается при двусмысленном толковании параметра.
#include <stdio.h> /* для printf */ #include <stdlib.h> /* для exit */ #include <getopt.h> int main (int argc, char **argv) { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 1, 0, 'c'}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:012", long_options, &option_index); if (c == -1) break; switch (c) { case 0: printf ("параметр %s", long_options[option_index].name); if (optarg) printf (" с аргументом %s", optarg); printf ("\n"); break; case '0': case '1': case '2': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("цифры используются в двух разных элементах argv.\n"); digit_optind = this_option_optind; printf ("параметр %c\n", c); break; case 'a': printf ("параметр a\n"); break; case 'b': printf ("параметр b\n"); break; case 'c': printf ("параметр c со значением `%s'\n", optarg); break; case 'd': printf ("параметр d со значением `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt возвратило код символа 0%o ??\n", c); } } if (optind < argc) { printf ("элементы ARGV, не параметры: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); }
Описание в POSIX.2 функции getopt() содержит техническую ошибку, рассмотренную в POSIX.2 Interpretation 150. В реализации GNU (и, возможно, во всех других реализациях) работа функции отличается от описанной в спецификации и является корректной.
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |