getopt:无法识别缺失的参数' :'和无效的' ? '

时间:2012-02-25 06:30:31

标签: c linux getopt

我使用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 个答案:

答案 0 :(得分:4)

来自man getopt

  

如果getopt()在argv中找到一个未包含在中的选项字符   optstring,或者如果它检测到缺少的选项参数,它返回'?'   并将外部变量optopt设置为实际选项字符。

所以你的程序行为是按照预期设计的。您可能会在手册页中将getopt的预期返回值与此语句混淆:

  

如果是第一个字符(跟随任何可选的'+'或' - '描述   上面的optstring是一个冒号(':'),然后getopt()返回':'   代替 '?'表示缺少选项参数。如果检测到错误,并且optstring的第一个字符不是冒号,并且外部变量opterr非零(这是默认值),则getopt()会输出错误消息。

所以尝试按如下方式声明你的optstring:

const char *optstring = ":abc:d";

答案 1 :(得分:3)

getopt()函数的POSIX版本指定:

  

如果getopt()遇到optstring中未包含的选项字符,则应返回<question-mark>('?')字符。如果它检测到缺少的option-argument,如果optstring的第一个字符是<colon><colon>字符('?',它将返回<question-mark>字符(':')否则。

由于您的optstr不是以:开头,而是应该返回?