getopt: невозможно распознать отсутствующий аргумент ':' и недействительные '? ' - PullRequest
2 голосов
/ 25 февраля 2012

Я написал простой код, используя getopt для понимания перспективы.

#include <stdio.h>
#include <unistd.h>

int main(int argc, char* argv[])
{

 /* Here since c is followed with colon, so 'c' takes an argument */
  const char *optstring = "abc:d";

  int ret;

  while((ret=getopt(argc, argv, optstring))!= -1)
  {
    switch(ret)
    {
      case 'a':
        printf("Option found: a, optind = %d\n",optind);
        break;

      case 'b':
         printf("Option found: b, optind = %d\n",optind);
         break;

      case 'c':
         printf("Option found: c, optind = %d\n",optind);
         printf("Option argument: %s\n",optarg);
         break;

      case 'd':
         printf("Option found: d, optind = %d\n",optind);
         break;

      case ':':
         printf("The option takes an argument which is missing");
         break;

     //case '?':
       //   printf("Didn't you enter an invalid option?");
           // break;
     }
   }
 }

Проблема:

(1) Дело 1: Если комментарий case '?' прокомментирован, то:

[root@dhcppc0 getopt]# ./a.out -a -b -c
    Option found: a, optind = 2
    Option found: b, optind = 3
    ./a.out: option requires an argument -- c

Итак, как вы можете видеть, case ':' не вступил в силу, так как обычно мы ожидаем, что отсутствующий аргумент вернет getopt ':' (двоеточие).

(2) Дело 2: И, если я откомментирую это, а затем запустите программу, она наберет case '? даже за отсутствующий аргумент.

enter code here
[root@dhcppc0 getopt]# ./a.out -a -b -c
   Option found: a, optind = 2
   Option found: b, optind = 3
      ./a.out: option requires an argument -- c
      Didn't you enter an invalid option?

Какой смысл я здесь упускаю?

ДОБАВЛЕНО ПОЗЖЕ :

Кроме того, почему ./a.out: option requires an argument -- c появляется ошибка по умолчанию? Как с этим справиться, так как я уже позаботился об этом в case ':' и не хочу сообщение об ошибке по умолчанию?

ДОБАВЛЕНО СНОВА : Как предложено в ответе, я использовал двоеточие в начале строки optstring - const char *optstring = ":abc:d", тогда почему это происходит?

./a.out -a -b -c -d returns -d as the argument to c?? -d is a separate optional character and not any argument

Ответы [ 2 ]

4 голосов
/ 25 февраля 2012

С man getopt :

Если getopt () находит символ опции в argv, который не был включен в optstring, или, если он обнаруживает отсутствующий аргумент option, он возвращает '?' и устанавливает для внешней переменной optopt фактический символ опции.

Таким образом, поведение вашей программы соответствует ожидаемому. Возможно, вы путаете ожидаемое возвращаемое значение getopt с этим утверждением на странице руководства:

Если первый символ (после любых необязательных '+' или '-' описан выше) строки optstring - это двоеточие (':'), затем getopt () возвращает ':' вместо '?' указать отсутствующий параметр аргумента. Если была обнаружена ошибка, и первый символ строки optstring не является двоеточием, а внешняя переменная opterr отлична от нуля (по умолчанию), getopt () выводит сообщение об ошибке.

Поэтому попробуйте объявить свою строку следующим образом:

const char *optstring = ":abc:d";
3 голосов
/ 25 февраля 2012

POSIX-версия функции getopt() указывает:

Если getopt() встречает символ опции, который не содержится в optstring, он должен возвращать символ <question-mark> ('?'). Если он обнаруживает отсутствующий аргумент-аргумент, он должен вернуть символ <colon> (':'), если первый символ строки optstring был <colon> или символ <question-mark> ('?') В противном случае.

Поскольку ваш optstr не начинается с :, он должен вернуть ?.

...