Getopt shift optarg

依然范特西╮ 提交于 2019-12-05 10:35:36
Kerrek SB

bar is not an option argument in the eyes of getopt. Rather, GNU getopt rearranges the positional arguments so that at the end of the processing, you have argv[3] being "hello" and argv[4] being "bar". Basically, when you're done getopting, you still have positional arguments [optind, argc) to process:

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]
     }
}

It depends on whether you're using GNU getopt() or not, and if you are, whether POSIXLY_CORRECT is set in the environment.

Classically (meaning non-GNU getopt()), all the option arguments must precede any non-option (file name) arguments. That would mean you have four non-option arguments.

If you have GNU getopt() and do not have POSIXLY_CORRECT set, then it will process option arguments anywhere on the command line. In that case, you'd have one option, -r with the argument value foo, and two non-option arguments (hello and bar).

To get Classic getopt() to recognize the -r, you'd have to require the first (non-option) argument and only then call getopt() at all:

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 can also return non-option arguments if you enable it to do so. Other than that, the bar argument will always be treated as a non-option argument.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!