Linux программирование в примерах - страница 24

стр.

>

> 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 из первого примера.

На практике следует писать свои программы так, чтобы у каждой короткой опции была также соответствующая длинная опция. В этом случае проще всего установить в >flag NULL, а в >val соответствующий единичный символ.

2.3.3.2. Длинные опции в стиле POSIX

Стандарт POSIX резервирует опцию >-W для специфических для производителя возможностей. Поэтому по определению >-W непереносимо между различными системами.

Если за >W в аргументе >optstring следует точка с запятой (обратите внимание не двоеточие), >getopt_long() рассматривает >-Wlongopt так же, как >--longopt. Соответственно в предыдущем примере измените вызов следующим образом:

>while ((с =

> getopt_long(argc, argv, ":f:W;", longopts, NULL)) != -1) {

С этим изменением >-Wall является тем же, что и >--all, a >-Wfile=myfile тем же, что >--file=myfile. Использование точки с запятой позволяет программе использовать при желании >-W в качестве обычной опции. (Например, GCC использует ее как нормальную опцию, тогда как >gawk использует ее для совместимости с POSIX.)

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;

> }

>}

В своих программах вы можете захотеть сделать для каждого символа опции комментарии, объясняющие их значение. Однако, если вы использовали описательные имена переменных для каждого символа опции, комментарии уже не так нужны. (Сравните