Проблемы с использованием getopt в C

Я хотел использовать getopt() для анализа аргументов, предоставленных в командной строке, но у меня возникли проблемы с очень простыми тестовыми примерами. У меня есть следующий код (который почти, но не полностью идентичен коду, предоставленному в качестве примера в Стандартное определение POSIX).

int main(int argc, char *argv[]) {
    int c;
    int rmsflg = 0, saflg = 0, errflg = 0;
    char *ifile;
    char *ofile;

    //Parse command line arguments using getopt
    while (((c=getopt(argc,argv, ":i:rso:")) != 1) && (errflg == 0))  {
        switch(c){
            case 'i':
                ifile="optarg";
                break;
            case 'o':
                ofile="optarg";
                break;
            case 'r':
                if (saflg)
                    errflg++;
                else {
                    rmsflg++;
                    printf("Root Mean Square averaging selected\n");
                }
                break;
            case 's':
                if (rmsflg)
                    errflg++;
                else {
                    saflg++;
                    printf("Standard Arithmetic averaging selected\n");
                }
                break;
            case ':':
                fprintf(stderr,"Option -%c requires an argument\n",optopt);
                errflg++;
                break;
            case '?':
                fprintf(stderr,"Option -%c is not a valid option\n",optopt);
                errflg++;
                break;
            default:
                fprintf(stderr,"The value of c is %c,\
                        the option that caused this error is -%c\n",c,optopt);
                errflg++;
                break;  
        }
    }
    if (errflg) {
        fprintf(stderr, "usage: xxx\n");
        exit(2);
    }
    return 0;
}

Во-первых, когда у меня нет регистра по умолчанию, ничего не выводится. Когда я вставил регистр по умолчанию и заставил его выводить значение, которое имеет c, я получаю ?. Это странно по 2 причинам. Во-первых, и это меня больше всего беспокоит, почему c не совпадает с регистром ?, который был специально написан для соответствия этому выводу, а скорее переходит к регистру default. Во-вторых, вывод optopt (для моего ввода) o. Символ ? возвращается только в том случае, если указанный параметр не соответствует ни одному символу в optstring.


person user999318    schedule 02.01.2014    source источник
comment
Какую командную строку вы используете для получения такого поведения? Какая платформа и инструменты задействованы? Я не вижу ничего подобного тому, что вы описываете. Поведение, которое я вижу, заключается в том, что если вы не передадите никаких параметров или только допустимые параметры, программа передаст их из-за неправильного теста для getopt(), выполняемого с обработкой arg, о которой Эмануэле Паолини упоминает в своем ответе. Допустимые параметры обрабатываются так, как вы ожидаете (с предложением default: или без него. Если добавлено предложение default:, программа выполняет его после завершения обработки аргументов (и, следовательно, не зависает).   -  person Michael Burr    schedule 02.01.2014
comment
Я вижу ошибку, которую я сделал в условии цикла while, и это решает проблему, но я все еще не понимаю, почему я получаю поведение, о котором я упоминал, которое точно описывает вывод, который я получаю в моей системе. Я использую компилятор командной строки XCode в OSX 10.9.1. Никаких дополнительных инструментов не требуется, только командная строка и текстовый редактор.   -  person user999318    schedule 02.01.2014
comment
У меня нет OSX, чтобы проверить это, но держу пари, причина, по которой вы видите такое поведение, заключается в том, что когда getopt() возвращал -1, не было совпадения регистра (до добавления предложения default:), поэтому ничего не выводилось. Программа будет бесконечно зацикливаться, а getopt() всегда будет возвращать -1. Когда вы добавляете предложение default:, там перехватывается результат -1. Я предполагаю, что вывод -1 со спецификацией формата %c отображается OSX как '?' поскольку -1 не соответствует символу кодовой страницы или шрифта. Теперь вы запутались - похоже, что getopt() вернул '?'. Попробуйте: printf("-1 as char: %c\n", -1);   -  person Michael Burr    schedule 02.01.2014


Ответы (1)


В условиях цикла while вы должны проверить возвращаемое значение getopt на соответствие -1, а не 1. Затем, если вы передадите параметр -? в командной строке, он должен быть распознан.

person Emanuele Paolini    schedule 02.01.2014