Роббинс Арнольд
Шрифт:
2.3.3 3. Сводка возвращаемых значений
getopt_long
Теперь должно быть ясно, что
getopt_long
предоставляет гибкий механизм для разбора опций. В табл. 2.2 приведена сводка всех возможных возвращаемых значений функции и их значение. Таблица 2.2. Возвращаемые значения
getopt_long
Возвращаемый код | Значение |
---|---|
0 | getopt_long установила флаг, как указано в таблице длинных опций |
1 | optarg указывает на простой аргумент командной строки |
'?' | Недействительная опция |
' ' | Отсутствующий аргумент опции |
'x' | Символ опции 'x' |
– 1 | Конец опций |
Наконец, мы улучшим предыдущий пример кода, показав оператор
switch
полностью: int do_all, do_help, do_verbose; /* флаговые переменные */
char *myfile, *user; /* файл ввода, имя пользователя */
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 },
{ "user" , optional_argument, NULL, 'u'},
{ 0, 0, 0, 0 }
};
...
while((c=getopt_long(argc, argv, ":ahvf:u::W;", longopts, NULL)) != -1) {
switch (c) {
case 'a':
do_all = 1;
break;
case 'f':
myfile = optarg;
break;
case 'h':
do_help = 1;
break;
case 'u':
if (optarg != NULL)
user = optarg;
else
user = "root";
break;
case 'v':
do_verbose = 1;
break;
case 0:
/* getopt_long установил переменную, просто продолжить */
break;
#if 0
case 1:
/*
* Используйте этот case, если getopt_long должна
* просмотреть все аргументы. В этом случае добавьте к
* optstring ведущий * символ '-'. Действительный код,
* если он есть, работает здесь.
*/
break;
#endif
case ':': /* отсутствует аргумент опции */
fprintf(stderr, "%s: option '-%c' requires an argument\n",
argv[0], optopt);
break;
case '?':
default: /* недействительная опция */
fprintf(stderr, "%s: option '-%c' is invalid: ignored\n",
argv[0], optopt);
break;
}
}
В своих программах вы можете захотеть сделать для каждого символа опции комментарии, объясняющие их значение. Однако, если вы использовали описательные имена переменных для каждого символа опции, комментарии уже не так нужны. (Сравните
do_verbose
и vflag
.) 2.3.3.4. GNU
getopt
или getopt_long
в программах пользователей Вы можете захотеть использовать в своих программах GNU
getopt
или getopt_long
и заставить их работать на не-Linux системах/ Это нормально; просто скопируйте исходные файлы из программы GNU или из CVS архива библиотеки С GNU (GLIBC) [30] . Исходные файлы getopt.h
, getopt.с
и getopt1.c
. Они лицензированы на условиях меньшей общедоступной лицензии (Lesser General Public License) GNU, которая позволяет включать библиотечные функции даже в патентованные программы. Вы должны включить в свою программу копию файла COPYING.LIB
наряду с файлами getopt.h
, getopt.с
и getopt1.с
.30
См.
http://sources.redhat.com
— Примеч. автора. Включите исходные файлы в свой дистрибутив и откомпилируйте их с другими исходными файлами. В исходном коде, вызывающем
getopt_long
, используйте '#include <getopt.h>
', а не '#include "getopt.h"
'. Затем, при компилировании, добавьте к командной строке компилятора С – I
. Таким способом сначала будет найдена локальная копия заголовочного файла. Вы можете поинтересоваться: «Вот так, я уже использую GNU/Linux. Почему я должен включать
getopt_long
в свой исполняемый модуль, увеличивая его размер, если процедура уже находится в библиотеке С?» Это хороший вопрос. Однако, здесь не о чем беспокоиться. Исходный код построен так, что если он компилируется на системе, которая использует GLIBC, откомпилированные файлы не будут содержать никакого кода! Вот подтверждение на нашей системе: