getopt_long没有按预期工作

时间:2015-12-03 14:33:56

标签: linux parsing command-line getopt-long

我有以下代码

#include <stdio.h>     
#include <getopt.h>       

int main(int argc, char* argv[]){
    const struct option longopts[]={
        {"one", required_argument, 0, '1'},
        {"two", required_argument, 0, '2'},
        {"three", required_argument, 0, '3'},
        {"four", required_argument, 0, '4'},
        {"five", required_argument, 0, '5'},
        {0,0,0,0}
    };

    const char* shortopts="1:2:3:4:5:";
    int c;
    c = -1;
    for(;;){
        int optind = 0;
        c = getopt_long(argc, argv, shortopts, longopts, &optind);
        if(c<0)
            break;
        switch(c){
            case 0:
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
                fprintf(stdout, "----------------------------------------\n");
                fprintf(stdout, "c = %c\n", c);
                fprintf(stdout, "optindd = %d\n", optind);
                fprintf(stdout, "val = %c, \n", longopts[optind].val);
                fprintf(stdout, "name = %s\n", longopts[optind].name);
                fprintf(stdout, "optarg = %s\n", optarg);
                break;
        }
    }

}

输入:

./a.out --one 1 -2 two --three 3 -4 four --five 5           

预期产量:
我想在遇到相应的shortopt / longopt时打印struct选项(name和val)的成员。

上面的代码打印出以下内容,带有一些意想不到的输出:

----------------------------------------
c = 1
optindd = 0
val = 1, 
name = one
optarg = 1
---------------------------------------- 
c = 2
optindd = 0           // expected 1
val = 1,         // expected 2      
name = one        // expected two
optarg = two
----------------------------------------
c = 3
optindd = 2
val = 3, 
name = three
optarg = 3
---------------------------------------- 
c = 4
optindd = 0          // expected 3
val = 1,        // expected 4
name = one       // expected four
val = four
----------------------------------------
c = 5
optindd = 4
val = 5, 
name = five
val = 5

我使用的是Ubuntu 14.04。

1 个答案:

答案 0 :(得分:2)

longindex的{​​{1}}返回参数仅针对长选项设置,而不是针对短选项设置。 getopt_long无法知道哪个长选项对应于给定的短选项(尽管通信对您来说似乎很明显)。如果找到一个短选项,则getopt_long变量保持不变,因此您应该初始化为可识别的值(如-1),而不是将其初始化为0.

顺便说一句,longindex是由optind维护的全局变量,一旦完成标记,您将需要处理位置参数。使用具有相同名称的局部变量覆盖此变量是不明智的(尽管是合法的);当你需要价值时,这既困扰了读者又令人尴尬。

这些都不能帮助您识别与给定的短选项相对应的长选项。如果您觉得需要这些信息,那完全是您的责任。例如,您可以在longopts结构中搜索与找到的短选项对应的getopt;然后,您必须处理给定的短期权在该结构中出现零次或多次的可能性。

作为一个简单的例子,而不是:

val
你可以做点什么:

int optindex = 0;
c = getopt_long(argc, argv, shortopts, longopts, &optindex);