5

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

./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 类似的方式来做到这一点?

谢谢。

4

2 回答 2

8

bar在 . 的眼中不是一个选项参数getopt。相反,GNUgetopt 重新排列了位置参数,以便在处理结束时,您有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]
     }
}
于 2012-04-07T21:54:47.273 回答
3

这取决于您是否使用GNUgetopt(),如果是,是否POSIXLY_CORRECT在环境中设置。

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

如果您有 GNUgetopt()并且没有POSIXLY_CORRECT设置,那么它将在命令行的任何位置处理选项参数。在这种情况下,您将有一个选项,-r带有参数 valuefoo和两个非选项参数(hellobar)。

要让 Classicgetopt()识别-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);
}

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

于 2012-04-07T22:15:06.847 回答