我使用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
答案 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
不是以:
开头,而是应该返回?
。