当遇到getopt或getopt_long遇到非法选项时,它会存储违规选项字符optopt.当非法选项是一个很长的选项时,我在哪里可以找到该选项是什么?然后有什么有意义的存储optopt吗?
我已设置opterr = 0禁止自动打印的错误消息.我想创建自己的消息,我可以打印或记录我想要的地方,但我想要包含无法识别的选项的名称.
你完全正确地看到了这些细节上的man页面,但是可以从源代码中收集到足够的提示,例如glibc在glibc-xyz/posix/getopt.c中的实现_getopt_internal_r.(也许这是这个GNU扩展函数唯一有趣的实现?)
optopt当遇到错误的长选项时,该代码设置为0,我认为这有助于区分这种情况与错误的短选项,当optopt肯定是非NUL时.
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;
}
Run Code Online (Sandbox Code Playgroud)
$ ./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行为不那么乐观.