значение getopt остается нулевым - PullRequest
5 голосов
/ 23 июня 2011

Я передаю свои входные данные программы и вижу их в argv, но у getopt нет аргумента, который я ожидаю.

Вот как я запускаю мою прогу: ./my_prog -X -f имя файла

<snip>
while ((opt = getopt(argc, argv, "Xf:eE:dD")) != EOF) {
    switch (opt) {
       case 'X':
       case 'f':
                if (optarg == NULL)
                fput("no point of living", fp);         << for debugging

</snip>

Я всегда получаю optarg как ноль. ПОЧЕМУ?

Ответы [ 3 ]

9 голосов
/ 23 июня 2011

Строка аргумента не имеет: после X (например, X: f), поэтому optarg всегда будет нулевым.

Я также укажу, что обычно в операторе switch вы хотитеперерыв после каждого случая (как правило, не всегда, но обычно при разборе аргументов), поэтому:

switch ( ... ) {
    case 'X': {
        // do something
    } break;

    case 'f': {
        // do something else
    } break;
}
1 голос
/ 20 июня 2014

Я только что имел дело с этой проблемой, и, похоже, на этот вопрос так и не был дан полный ответ.

Вы должны убедиться, что устанавливаете внешнюю переменную libc opterr = 0, прежде чем вызывать getopt; если вы не сбросите его и у getopt ранее была ошибка в другом приложении где-либо в вашей системе, которое использовало его, для этого аргумента произойдет сбой. Я также повторю существующую точку зрения, что, поскольку у вас нет оператора останова после case 'X':, это верный признак проблемы, поскольку она провалится.

getopt обрабатывает только один аргумент за раз, поэтому переход к регистру X к регистру f - плохая вещь. У вас всегда должен быть разрыв в каждом утверждении о случае switch, если вы не абсолютно уверены, что он должен провалиться (что очень редко в моем опыте). В качестве еще одного полезного примера, вы всегда должны заключать блоки кода в {} (ссылаясь на ваше условие), если только это не оператор return или break или что-то, из-за чего поток программы выпадает из текущего или область действия родительского блока или ввод новой области посредством вызова функции или метода.

Я думаю, что ваш вариант строки Xf: eE: dD в порядке. Это указывает на то, что:

1) Следующие флаги опций будут всегда иметь нулевой аргумент: XedD

2) Для следующих параметров потребуется аргумент: fE

Если это та функция, которую вы ищете, то данная строка параметров подходит. Если вы используете GNU libc, то для другого ответа выше вы можете использовать опцию :: after в строке опций, чтобы указать, что у опции может быть аргумент, но это не обязательно.

Итак, в верхней части файла убедитесь, что у вас есть хотя бы:

extern int opterr;

Затем, перед первым вызовом getopt в вашем коде, установите opterr на 0.

* * Например, тысяча тридцать один
opterr = 0;

while ((opt = getopt(argc, argv, "Xf:eE:dD")) != EOF) {
    switch (opt) {
       case 'X':
       case 'f':
                if (optarg == NULL)
                fput("no point of living", fp);         << for debugging

Это должно хотя бы частично решить вашу проблему. Вот ссылка на пример:

http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html

Приветствия

Jon

1 голос
/ 30 марта 2012

Для кого еще попасть на эту страницу: С http://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html#Using-Getopt: За символом опции в этой строке может следовать двоеточие (':'), чтобы указать, что он принимает обязательный аргумент.Если за символом опции следуют две двоеточия ('::'), его аргумент является необязательным;это расширение GNU.

, поэтому в качестве аргумента вы можете использовать: "X: f: e: E: d: D:"

Была такая же проблема.

...