C getopt multiple value
Мой аргумент таков:
./a.out -i file1 file2 file3
Как я могу использовать getopt()
для получения 3 (или более) входных файлов?
Я делаю что-то вроде этого:
while ((opt = getopt(argc, argv, "i:xyz.."))!= -1){
case 'i':
input = optarg;
break;
...
}
Я получаю только file1
; как получить file2
, file3
?
Ответы
Ответ 1
Если вам нужно, вы можете начать с argv[optind]
и приращения optind
самостоятельно. Тем не менее, я бы рекомендовал против этого, так как я считаю, что синтаксис является плохим. (Как вы знаете, когда вы достигли конца списка? Что делать, если у кого-то есть файл с именем -
в качестве первого символа?)
Я думаю, что было бы лучше изменить синтаксис:
/a.out -i file1 -i file2 -i file3
Или обрабатывать список файлов в качестве позиционных параметров:
/a.out file1 file2 file3
Ответ 2
Я знаю, что это довольно старый, но я нашел это в своем поиске решения.
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()) указывает на следующую позицию после "текущего argv", выбранного getopt();
Вот почему я уменьшаю его вначале.
Прежде всего, для проверки цикла, если значение текущего аргумента находится в границах argv (argc - длина массива, поэтому последняя позиция в массиве argv - argc-1).
Вторая часть && сравнивается, если следующий аргумент сначала char равен '-'. Если первый char равен '-', тогда у нас заканчиваются следующие значения для текущего аргумента else argv [optind] - наше следующее значение. И так до тех пор, пока argv не закончится или аргумент не закончится.
В конце инкремента optind проверить следующий argv.
Обратите внимание, что, поскольку мы проверяем 'optind < argc 'первая вторая часть условия не будет выполнена, если первая часть не верна, поэтому не стоит беспокоиться о чтении вне границ массива.
PS Я - совершенно новый программист на C, если у кого-то есть улучшения или критика, пожалуйста, поделитесь им.
Ответ 3
Обратите внимание на то, что расширение перестановок с неконформным расширением glibc нарушит любую попытку использовать несколько аргументов для -i
таким образом. И в системах, отличных от GNU, "второй аргумент -i
" будет интерпретироваться как первый аргумент без опционов, останавливая дальнейший разбор параметров. Учитывая эти проблемы, я бы отбросил getopt
и написал собственный синтаксический анализатор командной строки, если вы хотите использовать этот синтаксис, поскольку это не синтаксис, поддерживаемый getopt
.
Ответ 4
Я посмотрел и попробовал код выше, но я нашел свое решение немного легче и работал лучше для меня:
Мне нужна была обработка:
-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;
Это захватило первое значение, которое меня как нормальное, а затем просто искало второе значение REQUIRED.
Ответ 5
Вы можете указать свои входные файлы с не-пробельным символом, таким как запятая, и выполнить итерацию через них.
Например, если $files = "file1, file2, file3" -
for i in ${files//,/ } ; do
..do stuff with $i..
done