Предоставление двух аргументов для параметра командной строки с использованием getopt

есть ли альтернативный способ передать два аргумента опции в виде одной строки при использовании getopt? Обычно я бы сделал следующее:

./command -o "key value" [command arguments]

Тогда мне пришлось бы явно разделить строку аргумента

 while ((op = getopt(argc, argv, "o:")) != EOF) {
    switch (op) {
             case 'o': 
                 char* result = NULL;
                 result = strtok_r(optarg," ");
                 while(result) {
                     /* DO STUFF */
                     result = strtok(NULL," ");
                 }

                 break;
             default:
                 printUsage()
                 break;
   }

Итак, мне интересно, возможно ли сделать следующее:

./command -o key value [command arguments]

заставить getopt рассматривать «значение» как второй аргумент -o, а не как аргумент команды.


person ziu    schedule 19.12.2011    source источник


Ответы (2)


Стандарт POSIX getopt() не поддерживает несколько аргументов для одной буквы флага. Есть несколько вариантов, доступных для вас.

Один из вариантов — указать имена в качестве аргументов для отдельных букв опций (или использовать одно и то же дважды):

./command -o key -v value
./command -o key -o value

Другой вариант — использовать стандарт POSIX getsubopt() и нотацию командной строки, такую ​​как в качестве:

./command -o key=value

Это работает очень хорошо для вашего показанного сценария, если набор ключей относительно мал (не так хорошо, если они большие, но тогда вы можете обойтись без getsubopt() и просто разобрать optarg для = самостоятельно.

Другой вариант — написать синтаксический анализатор командной строки, который будет принимать несколько аргументов по мере необходимости. Я написал один, чтобы иметь возможность анализировать разнообразную и недисциплинированную обработку аргументов в программах, которые мы используем на работе, и это не так уж сложно (хотя и не совсем легко). В частности, он должен обрабатывать N (N > 1) значений параметров после одного флага. Свяжитесь со мной (см. мой профиль), если вы хотите посмотреть на источник. Есть несколько сложных проблем, которые нужно решить, например, что произойдет, если вы ожидаете 3 имени после буквы параметра, но один из первых трех аргументов начинается с дефиса - или появляется --. Я разрешаю только фиксированное количество аргументов, а не переменное число, но это отчасти потому, что мои варианты использования не должны охватывать переменное число (и это не звучит так, как если бы вы тоже).

person Jonathan Leffler    schedule 19.12.2011

Откуда getopt знать, где заканчиваются ваши -o возможности и где начинаются command arguments?

Один простой обходной путь — использовать спецификаторы -o:

$ cat t.c
#include<stdio.h>
#include<getopt.h>

int main(int argc, char **argv)
{
    char op;
    while ((op = getopt(argc, argv, "o:")) != EOF) {
        switch (op) {
            case 'o':
                printf("Option: %s\n", optarg);
                break;
            default:
                break;
        }
    }
}
$ gcc t.c
$ ./a.out -o one -o two -o three
Option: one
Option: two
Option: three
person Mat    schedule 19.12.2011
comment
Я знаю этот обходной путь, но поскольку два аргумента опции связаны вместе (пара ключ-значение), я не могу их разделить - person ziu; 19.12.2011
comment
Используйте два переключателя -ok key -ov val и добавьте немного логики, чтобы убедиться, что они указаны в правильном порядке. Или посмотрите другие варианты в предыдущем вопросе, который я связал. - person Mat; 19.12.2011