Getopt shift optarg

Мне нужно назвать мою программу так:

./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 ответа

bar не является аргументом выбора в глазах getopt, Скорее GNU getopt переставляет позиционные аргументы так, чтобы в конце обработки вы имели argv[3] быть "привет" и argv[4] быть "бар". По сути, когда вы закончите 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]
     }
}

Это зависит от того, используете ли вы GNU getopt() или нет, и если вы, будь то POSIXLY_CORRECT устанавливается в окружающей среде.

Классически (имеется в виду не GNU getopt()), все аргументы-опции должны предшествовать любым не-опциональным (имя файла) аргументам. Это будет означать, что у вас есть четыре неопционных аргумента.

Если у вас есть GNU getopt() и не имеют POSIXLY_CORRECT установить, тогда он будет обрабатывать аргументы параметров в любом месте командной строки. В этом случае у вас будет один вариант, -r со значением аргумента foo и два неопционных аргумента (hello а также bar).

Получить классический 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 Аргумент всегда будет рассматриваться как необязательный аргумент.

Другие вопросы по тегам