有人可以帮我解决getopt功能吗?
当我在main中执行以下操作时:
char *argv1[] = {"testexec","-?"};
char *argv2[] = {"testexec","-m","arg1"};
int cOption;
/* test for -? */
setvbuf(stdout,(char*)NULL,_IONBF,0);
printf("\n argv1 ");
while (( cOption = getopt (2, argv1, "m:t:n:fs?")) != -1) {
switch(cOption){
case 'm':
printf("\n -m Arg : %s \n",optarg);
break;
case '?':
printf("\n -? Arg ");
break;
case 'n':
printf("\n -n Arg : %s \n",optarg);
break;
}
}
printf("\n argv2 ");
while (( cOption = getopt (3, argv2, "m:t:n:fs?")) != -1) {
switch(cOption){
case 'm':
printf("\n -m Arg : %s \n",optarg);
break;
case '?':
printf("\n -? Arg : %s \n",optarg);
break;
case 'n':
printf("\n -n Arg : %s \n",optarg);
break;
}
}
我在使用旧libc版本的rhel3上运行此代码。我不知道哪一个是准确的。
现在问题是getopt在第二次使用argv2时无效。 但是如果我用argv1注释掉第一个getopt调用,它就可以工作。
有人可以告诉我这里我做错了什么吗?
答案 0 :(得分:12)
argv1和2必须以0结尾:
char* argv1[] = {"par1", "par2", 0};
编辑:好的,我读了getopt手册页,我发现了这个:
变量optind是argv中要处理的下一个元素的索引。系统初始化此值 1.调用者可以将其重置为1以重新开始扫描相同的argv,或者扫描新的参数向量。
因此,在getopt的两次调用之间使optind = 1使其按预期工作。
答案 1 :(得分:4)
getopt()
函数使用一些全局变量(如optind
和optarg
)来存储调用之间的状态信息。处理完一组选项后,这些变量中会留下导致下一组选项出现问题的数据。您可能会尝试通过清除变量来重置调用之间的getopt
状态,但我不确定这是否可行,因为该函数可能会使用其他未记录的变量而您永远不会知道得到了所有这些;此外,它绝对不可移植(即如果getopt()
的实现发生变化,则代码中断)。有关详细信息,请参阅man page。如果可以提供帮助,最好不要在给定程序中使用getopt()
多个参数集。
我不确定是否有一个实际的函数来重置getopt
的状态(或者可能是函数的可重入版本,它允许你将状态存储在你自己的变量中)...我似乎记得曾经看过类似的东西,但我现在找不到它了: - /
答案 2 :(得分:2)
如手册页所述:
“扫描多个参数向量,或多次重新扫描同一向量的程序,并希望在optstring的开头使用GNU扩展,如'+'和' - ',或者更改POSIXLY_CORRECT的值在扫描之间,必须通过将optind重置为0来重新初始化getopt(),而不是传统的值1.(重置为0强制调用内部初始化例程,重新检查POSIXLY_CORRECT并检查optstring中的GNU扩展。)“
答案 3 :(得分:1)
你有没有理由不使用getopt_long()?在大多数平台上,getopt()只调用带有开关的_getopt_long()来禁用长参数。对于我所知道的(仍在使用中)几乎所有平台都是这种情况,包括Linux,BSD,甚至像HelenOS这样的新兴操作系统 - 我知道,我是将getopt移植到其libc的人:)
使用你的程序的任何人都可以更容易地获得长期选项,至少在他们习惯使用它之前。
getopt_long()将允许您使用两个(或更多)选项索引,这些选项索引在完成处理参数后可以保持“实时”,只需要重新设置内部(全局,非重入)选项没什么大不了的。
这使您可以轻松地将参数计数与两次调用中实际传递的选项数量进行比较,并具有许多其他优点。请考虑不要使用过时的界面。
看看getopt.h,你会明白我的意思。