3

我使用 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
4

2 回答 2

4

man getopt

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

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

如果 optstring 的第一个字符(在上述任何可选的 '+' 或 '-' 之后)是冒号 (':'),则 getopt() 返回 ':' 而不是 '?' 表示缺少选项参数。如果检测到错误,并且 optstring 的第一个字符不是冒号,并且外部变量 opterr 不为零(这是默认值),则 getopt() 会打印一条错误消息。

因此,尝试如下声明您的 optstring:

const char *optstring = ":abc:d";
于 2012-02-25T06:42:49.583 回答
4

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

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

由于您的optstr不是以 a 开头:,因此它应该返回 a ?

于 2012-02-25T06:44:58.680 回答