C, Как происходит обновление getopt()

Я пытаюсь понять часть скелетного кода для класса. Предполагаемое использование будет:

./a.out -d -n Foo -i Bar

Скелетный код работает нормально, но я никогда не использовал getopt() и не могу понять, почему он работает правильно (понимание, что это не имеет никакого отношения к присваиванию, я просто хочу понять это). Как получается, что он обновляет/выходит из цикла while? Я не вижу увеличения указателя или аргументов, переданных ему в цикле, вообще.

char *optString = "-d-n:-i:";
int opt = getopt(argc, argv, optString);

while (opt != -1) {
    switch(opt) {
    case 'd':
        debug = 1;
        break;
    case 'n':
        nameserver_flag = 1;
        nameserver = optarg;
        break;
    case 'i':
        hostname = optarg;
        break;
    case '?':
        usage();
        exit(1);
    default:
        usage();
        exit(1);
    }
    opt = getopt(argc, argv, optString);
}

person asimes    schedule 26.09.2013    source источник
comment
libc, предоставляющая getopt, является свободным программным обеспечением. Просто изучите исходный код, если хотите в деталях понять, как это работает. И вы также можете использовать argp функции.   -  person Basile Starynkevitch    schedule 26.09.2013
comment
См. getopt.c из GNU libc.   -  person Basile Starynkevitch    schedule 26.09.2013
comment
@BasileStarynkevitch, спасибо, это помогает гораздо больше, чем справочные страницы, для понимания того, почему это работает. Похоже, optarg - это скрытый индекс   -  person asimes    schedule 26.09.2013
comment
Как указал Алекс Браулт в моем ответе (который я удалил), optarg не является скрытым индексом. почитаю внимательнее   -  person asimes    schedule 26.09.2013
comment
@asimes: наиболее важным моментом является то, что getopt определяет глобальные переменные, которые позже используются для возобновления выполнения. То, как именно они работают (за исключением 4 общедоступных), является деталью реализации и на самом деле не важно, кроме знания того, что он сохраняет состояние в памяти и считывает его обратно.   -  person 3Doubloons    schedule 26.09.2013
comment
Да, но я хотел иметь некоторое представление о том, что он делает для достижения своих целей. Сначала просто не понимал, как это возможно, пока не понял, что существуют скрытые переменные.   -  person asimes    schedule 26.09.2013


Ответы (2)


getopt использует глобальные переменные для хранения индекса аргумента, следующего символа для анализа и некоторой другой информации. Каждый раз, когда вы вызываете getopt, функция проверяет эти переменные, чтобы узнать, где она была в последний раз (или где вы сказали ей, что она была), и обновляет переменные для следующего вызова.

Самое главное, optind хранит индекс в argv следующего элемента, который нужно просканировать.

person 3Doubloons    schedule 26.09.2013

Каждый вызов getopt обрабатывает еще один из аргументов в argv, возвращая результат в opt и т.д. и т.п. Что еще тут понимать?

person Mike Makuch    schedule 26.09.2013
comment
Аргумент, который он принимает в цикле while, не обновляется никаким видимым образом. - person asimes; 26.09.2013
comment
Да, argv не меняется. getopt поддерживает состояние с переменной, которую вы не видите, включенной в заголовочный файл. Однако opt меняется, так работает ваш оператор switch. Подробности смотрите в 'man getopt'. - person Mike Makuch; 26.09.2013