Поместите операнды первыми в getopt()

Используя функцию getopt() в C, это можно сделать:

program -a arg_for_a -b arg_for_b -c operand1 operand2

и работает без проблем.

Но как заставить это работать таким образом?:

program operand1 operand2 -a arg_for_a -b arg_for_b -c

В этом случае каждый аргумент, включая -a, -b и т. д., считается операндом.

Я пытаюсь сделать так же, как gcc или ssh:

gcc code.c -o executable
ssh user@host -i file.pem

То есть, в какой бы позиции ни стояли опции и операнды, они распознаются корректно.

Как сделать так, чтобы параметры правильно распознавались, где бы они ни находились, и каждое слово, которое не следует за параметром, распознавалось как операнд?


person João Paulin    schedule 17.07.2013    source источник
comment
Вы можете проанализировать аргументы (предоставленные main) вручную. gcc делает это!   -  person Basile Starynkevitch    schedule 17.07.2013


Ответы (1)


Если вы используете реализацию getopt из библиотеки GNU C, то она будет работать так же, как и все утилиты GNU, потому что почти все они ее используют. В частности, (цитата из man 3 getopt):

По умолчанию getopt() переставляет содержимое argv при сканировании, так что в конечном итоге все неопции оказываются в конце.

Это не совсем то же самое, что gcc. gcc заботится об относительном порядке необязательных и позиционных аргументов. (Например, имеет значение, где -l находится в командной строке.) Чтобы сделать это, вам нужно указать GNU getopt не переставлять аргументы. Затем каждый раз, когда getopt сообщает, что это сделано, optind будет иметь индекс следующего позиционного аргумента (если он есть). Затем вы можете использовать этот аргумент, увеличить optind и продолжить использовать getopt, что продолжится со следующего аргумента.

person rici    schedule 17.07.2013
comment
Если вы установите переменную окружения POSIXLY_CORRECT, GNU getopt() будет настаивать на том, чтобы параметры шли перед параметрами без параметров, как и задумал Бог (хорошо, я имею в виду «как задумали Деннис, Кен и их команда» и «как требует POSIX»). - person Jonathan Leffler; 17.07.2013
comment
Кроме того, если у вас GNU getopt(), вы можете поместить - в начало строки параметров. Затем он будет возвращать аргументы, не являющиеся параметрами, по мере их обнаружения, поэтому вы можете последовательно обрабатывать файлы и параметры. Возврат из getopt() равен 0, когда встречается аргумент, не являющийся параметром. - person Jonathan Leffler; 17.07.2013