Linux программирование в примерах | страница 39



На практике следует писать свои программы так, чтобы у каждой короткой опции была также соответствующая длинная опция. В этом случае проще всего установить в >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() должна

>   * просмотреть все аргументы. В этом случае добавьте к