C';s getopt无法分析argv末尾(或中间)的选项
我喜欢解析C';s getopt无法分析argv末尾(或中间)的选项,c,glibc,getopt,unistd.h,C,Glibc,Getopt,Unistd.h,我喜欢解析argv参数中的选项。不幸的是,我无法对非选项之间或argv末尾的getopt解析选项。示例程序: #include <stdio.h> #include <unistd.h> int o_help = 0; int main(int argc, char *argv[]) { int opt, i; while ((opt = getopt(argc, argv, "h")) != -1) { switch (opt) {
argv
参数中的选项。不幸的是,我无法对非选项之间或argv
末尾的getopt
解析选项。示例程序:
#include <stdio.h>
#include <unistd.h>
int o_help = 0;
int main(int argc, char *argv[]) {
int opt, i;
while ((opt = getopt(argc, argv, "h")) != -1) {
switch (opt) {
case 'h':
o_help = 1;
break;
default:
return -1;
}
}
printf("o_help=%d\n", o_help);
for (i = 1; i < argc; i++) {
printf("%s ", argv[i]);
}
printf("\n");
return 0;
}
官方的getopt
手册页说明:
默认情况下,getopt()在扫描argv时会排列argv的内容,因此最终所有非选项都位于末尾
因为我没有另外指定,所以我希望默认行为为1。解析
-h
选项和2。排列argv
,使非选项位于数组的末尾。不幸的是,像调用/a.out hello-h world
这样的程序既不能解析-h
也不能排列数组。非常感谢您的帮助。您正在查看手册页面中的getopt()
版本。Alpine Linux不使用glibc,而是使用
查看两者之间的差异,您可以从musl libc wiki中阅读:
GNU getopt将argv置于非选项参数之前,将选项拉到前面musl和POSIX标准getopt在第一个非选项参数处停止处理选项,不进行排列
因此,这里的解决方案是:
getopt()
之前,请使用musl,但请自己排列argv
Marco的回答是正确的,但是如果您没有使用基于glibc的发行版,“自己安装glibc”确实不是一个好建议;你将独自构建一个完整的平行图书馆生态系统。对于您的问题,有两种标准的解决方案,它们要简单得多 GNU认可的使用非标准GNU行为(如您想要的)的方法是使用gnulib和autoconf,它可以根据需要自动用GNU版本替换getopt。然而,这是一个巨大的变化,它要求你的程序是GPL的
一个更简单的解决方案是只使用
getopt_long
和一个退化的长选项列表,而不是getopt
。由于getopt_long
不是一个标准的受管函数,而是最初在GNU上定义的扩展,musl对它的实现可以自由地遵循GNU的行为,即排列argv
,以允许混合选项和非选项参数,并且这样做。无法复制(使用Ubuntu)。您是否设置了正确的环境变量?对于glibc版本的getopt()
,这将给出您看到的结果。(我假设alpine容器指的是alpine Linux虚拟机。如果它是其他东西,并且您使用的是OS X版本的getopt()
,但查看glibc文档…)实际上,alpine使用的是musl,而不是glibc。所以,是的。确定您看到的是正确的文档吗?@Shawn我正在使用docker,它在OS X上作为进程运行。我使用apk add libc dev
安装了标准库,我不确定这是否是glibc
实现。但您可能是对的,例如,上的OS X手册页没有提供这样的行为:“当所有选项都已处理(即,直到第一个非选项参数),getopt()返回-1如果您没有使用基于glibc的发行版,“自行安装glibc”确实不是一个好建议;你将独自构建一个完整的平行图书馆生态系统。我将发布一个更好的替代方案。@R..GitHubSTOPHELPINGICE您不打算自己构建任何东西,它已经打包并可在一秒钟内安装。OP将需要构建他们正在编写/构建的任何软件,这可能取决于库的生态系统,而不仅仅是libc。此外,Apline没有提供用于针对glibc进行编译的glibc交叉编译器,因此他们也必须进行设置。非常感谢,我从来没有检查过getopt_long
的文档-这非常棒,事实上,我刚刚检查过musl
实现,它还将argv置换到musl
实现中。
$ gcc prog.c
$ ./a.out hello -h world
o_help=0
hello -h world
$ ./a.out -h hello world
o_help=1
-h hello world