C getopt множественное значение - PullRequest
19 голосов
/ 15 октября 2010

Мой аргумент такой:

./a.out -i file1 file2 file3

Как я могу использовать getopt() для получения 3 (или более) входных файлов?Я делаю что-то вроде этого:

while ((opt = getopt(argc, argv, "i:xyz.."))!= -1){
  case 'i':
     input = optarg; 
     break;
  ...
}

Я получаю только file1;как получить file2, file3?

Ответы [ 4 ]

28 голосов
/ 02 ноября 2011

Я знаю, что это довольно старо, но я столкнулся с этим в поисках решения.

while((command = getopt(argc, argv, "a:")) != -1){

    switch(command){
        case 'a':

        (...)

        optind--;
        for( ;optind < argc && *argv[optind] != '-'; optind++){
              DoSomething( argv[optind] );         
        }

        break;
    }

Я обнаружил, что int optind (extern используется getopt () ) указывает на следующую позицию после 'current argv ', выбранного с помощью getopt () ;Вот почему я уменьшаю его в начале.

Прежде всего for loop проверяет, находится ли значение текущего аргумента в границах argv ( argc - длина массива, последняяпозиция в массиве argv равна argc-1 ).Вторая часть && сравнивает, является ли первый символ следующего аргумента '-'.Если первый символ равен '-', то у нас заканчиваются следующие значения для текущего аргумента, иначе argv [optind] является нашим следующим значением.И так до тех пор, пока argv не закончится или аргумент не закончится со значениями.

В конце увеличьте optind , чтобы проверить следующий аргумент argv.

Обратите внимание, потому что мыпроверка ' optind ' первой второй части условия не будет выполнена, если только первая часть не истинна, поэтому не стоит беспокоиться о чтении за пределами границ массива.

PS Я совершенно новый программист на C, если у кого-то есть улучшения или критика, пожалуйста, поделитесь им.

9 голосов
/ 15 октября 2010

Если нужно, вы можете начать с argv[optind] и увеличить optind самостоятельно. Тем не менее, я бы рекомендовал против этого, так как я считаю, что синтаксис плохой формы. (Как вы узнали бы, когда достигли конца списка? Что если у кого-то есть файл с именем - в качестве первого символа?)

Я думаю, что было бы еще лучше изменить ваш синтаксис на:

/a.out -i file1 -i file2 -i file3

Или обработать список файлов как позиционные параметры:

/a.out file1 file2 file3
6 голосов
/ 15 октября 2010

Обратите внимание, что расширение перестановки неконформных аргументов в glibc прервет любую попытку использовать несколько аргументов для -i таким образом.А в не-GNU системах «второй аргумент -i» будет интерпретироваться как первый не опциональный аргумент, что останавливает любой дальнейший анализ опций.Помня об этих проблемах, я бы выбрал getopt и написал свой собственный анализатор командной строки, если вы хотите использовать этот синтаксис, поскольку он не поддерживается синтаксисом getopt.

5 голосов
/ 11 августа 2012

Я посмотрел и попробовал приведенный выше код, но нашел решение немного проще и сработал лучше для меня:

Обработка, которую я хотел, была:

-m mux_i2c_group mux_i2c_out

(требуется 2 аргумента).

Вот как это получилось для меня:

case 'm':
    mux_i2c_group = strtol(optarg, &ch_p, 0);

    if (optind < argc && *argv[optind] != '-'){
        mux_i2c_out = strtol(argv[optind], NULL, 0);
        optind++;
    } else {
        fprintf(stderr, "\n-m option require TWO arguments <mux_group> "
                        "<mux_out>\n\n");
        usage();
    }

    use_mux_flag = 1;
    break;

Это захватило первое значение из меня как обычно, а затем просто искало второе, ОБЯЗАТЕЛЬНОЕ значение.

...