C 命令行处理库-getopt

C 命令行处理库-getopt,c,getopt,C,Getopt,有人能帮我使用getopt函数吗 当我主要执行以下操作时: 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?"))

有人能帮我使用getopt函数吗

当我主要执行以下操作时:

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;
    }
}
我在rhel3上运行这段代码,它使用旧的libc版本。我不知道哪一个是准确的

现在的问题是getopt在argv2中第二次不起作用。 但是如果我用argv1注释掉第一个getopt调用,它就可以工作了


有人能告诉我我做错了什么吗?

argv1和arg2必须以0结尾:

char* argv1[] = {"par1", "par2", 0};
编辑:好的,我阅读了getopt手册页,发现:

变量optind是要在argv中处理的下一个元素的索引。系统初始化此值 对1。调用者可以将其重置为1以重新扫描同一argv,或者在扫描新参数向量时将其重置为1

因此,在getopt的两个调用之间设置optind=1可以使其按预期工作。
getopt()
函数使用一些全局变量,如
optind
optarg
,来存储调用之间的状态信息。处理完一组选项后,这些变量中仍有导致下一组选项出现问题的数据。您可以通过清除变量来尝试在调用之间重置
getopt
的状态,但我不确定这是否可行,因为函数可能会使用其他未记录的变量,并且您永远不知道是否已获得所有变量;此外,它将是绝对不可移植的(即,如果
getopt()
的实现发生更改,则代码将中断)。有关详细信息,请参阅。最好不要对给定程序中的多个参数集使用
getopt()
,如果可以的话


我不确定是否有一个实际的函数来重置
getopt
的状态(或者该函数的可重入版本,它允许您将状态存储在自己的变量中)。。。我似乎记得曾经看到过类似的东西,但现在我看不到了:-/

有什么理由不使用getopt_long()来代替它吗?在大多数平台上,getopt()只调用带有开关的_getopt_long(),以禁用长参数。我所知道的几乎所有平台(仍在使用中)都是如此,包括Linux、BSD,甚至像HelenOS这样的新兴操作系统,我知道,是我将getopt移植到其libc:)

使用您的程序的任何人都更容易拥有长的选项,至少在他们习惯使用它之前是这样

getopt_long()将允许您使用两个(或更多)选项索引,它们在处理完参数后可以保持“活动”,只有内部(全局、不可重入)索引需要重新设置,这没什么大不了的

这使您可以轻松地将参数计数与两次调用中实际传递的选项数进行比较,并获得许多其他好处。。请考虑不要使用过时的接口。


看看getopt.h,你会明白我的意思。

如手册中所述:


“如果程序扫描多个参数向量,或者多次重新扫描同一个向量,并且希望在optstring的开头使用GNU扩展名,例如“+”和“-”,或者在扫描之间更改POSIXLY_CORRECT的值,则必须通过将optind重置为0(而不是传统的值1)来重新初始化getopt()。(重置为0将强制调用内部初始化例程,该例程将重新检查POSIXLY_CORRECT并检查optstring中的GNU扩展。)

回答得不错,但尽管这肯定是真的,但我尝试在示例代码中更改它,但它并没有解决被问及的特定问题。David,你是对的。我刚刚发现了这个错误,忘记了其余的:)我编辑了答案,因为我注意到,如果将optind值更新为1,代码将按预期工作。RegardsWare:POSIX标准没有说明将optind重置为1会将getopt()重置为初始状态,特别是在没有完全解析第一个参数的情况下。例如,如果第一个参数是-xy,并且您在处理x之后停止,则无法保证optind的重置工作正常。定义大多数平台?HP-UX、Solaris、AIX-getopt()不调用getopt_long()。这是6个Unix变体中的3个(BSD、Linux、MacOS X是其他重要的变体)。