Getopt转移optarg

时间:2012-04-07 21:49:57

标签: c getopt

我需要像这样调用我的程序:

./program hello -r foo bar

我从argv [1]中打招呼,但是我在价值条上遇到了麻烦,我还应该将“r:”更改为其他内容吗?

while((c = getopt(argc, argv, "r:")) != -1){
   switch(i){
   ...
   case 'r':
     var_foo = optarg;
     //shell like argument shift here?
     var_bar = optarg;
     break;
...}

我知道我可以通过传递argv来做到这一点,但有没有办法用getopt与bash类似的方式来做呢?

感谢。

2 个答案:

答案 0 :(得分:8)

bar的眼中,

getopt不是一个选项参数。相反,GNU getopt 重新排列位置参数,以便在处理结束时,argv[3]为“hello”,argv[4]为“bar”。基本上,当你完成getopting时,你仍然需要处理位置参数[optind, argc)

int main(int argc, char * argv[])
{
     {
         int c;
         while ((c = getopt(argc, argv, ...)) != -1) { /* ... */ }
     }

     for (int i = optind; i != argc; ++i)
     {
         // have positional argument argv[i]
     }
}

答案 1 :(得分:3)

这取决于您是否使用GNU getopt(),如果是,则是否在环境中设置了POSIXLY_CORRECT

经典(意思是非GNU getopt()),所有选项参数必须在任何非选项(文件名)参数之前。这意味着你有四个非选项参数。

如果你有GNU getopt()并且没有设置POSIXLY_CORRECT,那么它将在命令行的任何地方处理选项参数。在这种情况下,您有一个选项-r,参数值为foo,两个非选项参数(hellobar)。

要让经典getopt()识别-r,您必须要求第一个(非选项)参数,然后才会调用getopt()

int main(int argc, char **argv)
{
    char *cmd = argv[1];
    int   opt;

    argv[1] = argv[0];
    argv++;
    argc--;

    while ((opt = getopt(argv, argc, "r:")) != EOF)
    {
        switch (opt)
        {
        case 'r':
            ...capture optarg...
            break;
        default:
            ...report error....
            break;
        }
    }

    for (int i = optind; i < argc; i++)
        process_non_option_argument(cmd, argv[i]);

    return(0);
}

如果启用它,GNU getopt也可以返回非选项参数。除此之外,bar参数将始终被视为非选项参数。