6

有人可以帮助我使用 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;
    }
}

我在使用旧 libc 版本的 rhel3 上运行此代码。我不知道准确的说是哪一个。

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

有人可以告诉我我在这里做错了什么吗?

4

4 回答 4

13

argv1 和 2 必须以 0 结尾:

char* argv1[] = {"par1", "par2", 0};

编辑:好的,我阅读了 getopt 手册页,发现了这个:

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

因此,在 getopt 的两个调用之间设置 optind=1 可以使其按预期工作。

于 2009-02-11T07:45:22.583 回答
4

getopt()函数使用一些全局变量(如optindand optarg)来存储调用之间的状态信息。处理完一组选项后,这些变量中会留下数据,这些数据会导致下一组选项出现问题。您可能会尝试getopt通过清除变量来重置调用之间的状态,但我不确定这是否会起作用,因为该函数可能会使用其他未记录的变量,并且您永远不会知道您是否已全部获取; 此外,它绝对是不可移植的(即,如果getopt()更改的实现,您的代码会中断)。有关详细信息,请参见手册页。如果可以的话,最好不要getopt()在给定程序中使用超过一组参数。

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

于 2009-02-11T07:48:20.720 回答
2

如手册页所述:

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

于 2013-10-01T12:54:37.180 回答
1

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

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

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

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

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

于 2009-02-11T08:04:32.397 回答