当getopt
或getopt_long
遇到非法选项时,它会将违规选项字符存储在optopt
中。当非法选项是 long 选项时,我在哪里可以找到该选项的含义?并且有意义的事情是否存储在optopt
那么?
我已将opterr = 0
设置为禁止自动打印的错误消息。我想创建自己的消息,我可以打印或记录我想要的地方,但我想要包含无法识别的选项的名称。
答案 0 :(得分:7)
你完全正确地看到了这些细节上的man页面,但是可以从源代码中收集到足够的提示,例如glibc在glibc-x.y.z / posix / getopt.c的_getopt_internal_r
中的实现。 (也许这是这个GNU扩展函数唯一有趣的实现?)
当遇到错误的长选项时,该代码将optopt
设置为0,我认为当optopt
肯定是非NUL时,我认为将这种情况与错误的短选项区分开来是有用的。 / p>
当opterr != 0
主要将错误的长选项打印为argv[optind]
时产生的错误消息,以及稍后的代码(总是或 - 保守地 - 至少大部分)稍后会增加optind
返回。
因此考虑这个程序:
#include <getopt.h>
#include <stdio.h>
int main(int argc, char **argv) {
struct option longopts[] = {
{ "foo", no_argument, NULL, 'F' },
{ NULL, 0, NULL, 0 }
};
int c;
do {
int curind = optind;
c = getopt_long(argc, argv, "f", longopts, NULL);
switch (c) {
case 'f': printf("-f\n"); break;
case 'F': printf("--foo\n"); break;
case '?':
if (optopt) printf("bad short opt '%c'\n", optopt);
else printf("bad long opt \"%s\"\n", argv[curind]);
break;
case -1:
break;
default:
printf("returned %d\n", c);
break;
}
} while (c != -1);
return 0;
}
$ ./longopt -f -x --bar --foo
-f
./longopt:无效选项 - 'x'
坏短的选择'x'
./longopt:无法识别的选项'--bar'
糟糕的长期选择“ - 栏”
--foo
因此,在这些情况下,通过缓存getopt_long
的前optind
值,我们可以轻松打印出与opterr
消息相同的错误选项。
这在所有情况下都可能不太正确,因为glibc实现使用自己的__nextchar
而非argv[optind]
(在“无法识别的选项”案例中)值得研究,但它应该足够了让你入门。
如果您仔细考虑optind
与getopt_long
的重复调用之间的关系,我认为打印argv[cached_optind]
将非常安全。 optopt
存在是因为对于短选项,您需要知道单词中哪个字符是问题,但对于长选项,问题是整个当前单词(模数剥离选项参数的表格=param
)。当前的单词是getopt_long
正在查看的(传入的)optind
值。
如果文档中没有保证,我会对利用optopt = 0
行为不那么乐观。
答案 1 :(得分:4)
我能找到的最接近的是,如果你得到一个BADCH
,那么导致它的argv
项就在argv[optind-1]
。似乎应该有更好的方法来找到问题论点。