Linux программирование в примерах
Часть 17 из 253 Информация о книге
Наконец, мы улучшим предыдущий пример кода, показав оператор
полностью:switchint 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;elseuser = "root";break;case 'v':do_verbose = 1;break;case 0:/* getopt_long() установил переменную, просто продолжить */break;#if 0case 1:/** Используйте этот case, если getopt_long() должна* просмотреть все аргументы. В этом случае добавьте к* optstring ведущий * символ '-'. Действительный код,* если он есть, работает здесь.*/break;#endifcase ':': /* отсутствует аргумент опции */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.)vflag2.3.3.4. GNU
илиgetopt()в программах пользователейgetopt_long()Вы можете захотеть использовать в своих программах GNU
илиgetopt()и заставить их работать на не-Linux системах/ Это нормально; просто скопируйте исходные файлы из программы GNU или из CVS архива библиотеки С GNU (GLIBC) [30]. Исходные файлыgetopt_long(),getopt.hиgetopt.с. Они лицензированы на условиях меньшей общедоступной лицензии (Lesser General Public License) GNU, которая позволяет включать библиотечные функции даже в патентованные программы. Вы должны включить в свою программу копию файлаgetopt1.cнаряду с файламиCOPYING.LIB,getopt.hиgetopt.с.getopt1.сВключите исходные файлы в свой дистрибутив и откомпилируйте их с другими исходными файлами. В исходном коде, вызывающем
, используйте 'getopt_long()', а не '#include <getopt.h>'. Затем, при компилировании, добавьте к командной строке компилятора С#include "getopt.h". Таким способом сначала будет найдена локальная копия заголовочного файла.-IВы можете поинтересоваться: «Вот так, я уже использую GNU/Linux. Почему я должен включать
в свой исполняемый модуль, увеличивая его размер, если процедура уже находится в библиотеке С?» Это хороший вопрос. Однако, здесь не о чем беспокоиться. Исходный код построен так, что если он компилируется на системе, которая использует GLIBC, откомпилированные файлы не будут содержать никакого кода! Вот подтверждение на нашей системе:getopt_long()$ <b>uname -а</b> /* Показать имя и тип системы */Linux example 2.4.18-14 #1 Wed Sep 4 13:35:50 EDT 2002 i686 i686 i386 GNU/Linux$ <b>ls -l getopt.о getopt1.о</b> /* Показать размеры файлов */-rw-r--r-- 1 arnold devel 9836 Mar 24 13:55 getopt.о-rw-r--r-- 1 arnold devel 10324 Mar 24 13:55 getopt1.о$ <b>size getopt.о getopt1.о</b> /* Показать включенные в исполняемыймодуль размеры */text data bss dec hex filename0 0 0 0 0 getopt.о0 0 0 0 0 getopt1.оКоманда
печатает размеры различных составных частей двоичного объекта или исполняемого файла. Мы объясним вывод в разделе 3.1 «Адресное пространство Linux/Unix». Что важно понять прямо сейчас, это то, что несмотря на ненулевой размер самих файлов, они не вносят никакого вклада в конечный исполняемый модуль. (Думаем, это достаточно ясно.)size