0Pricing
C Academy · Урок

getopt

Стандартный разбор параметров

«getopt» — бесплатный урок C Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C Academy содержит 4 уроков всего.

Что такое getopt

getopt — это функция POSIX, которая разбирает однобуквенные опции в соответствии со стандартными соглашениями Unix.

Она находится в <unistd.h> и избавляет от большей части шаблонного кода при ручном разборе флагов.

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "v")) != -1) {
        if (opt == 'v') printf("verbose on\n");
    }
    return 0;
}

Строка optstring

Третий аргумент getopt — это строка опций: список допустимых букв опций.

"abc" означает, что -a, -b и -c принимаются как логические флаги.

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "abc")) != -1) {
        printf("saw option -%c\n", opt);
    }
    return 0;
}

Цикл разбора

При каждом вызове getopt возвращает следующий символ опции или -1, если разбор завершён.

Стандартный шаблон — цикл while с расположенным внутри switch, который выбирает действие по возвращённому символу.

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "xy")) != -1) {
        switch (opt) {
            case 'x': printf("x set\n"); break;
            case 'y': printf("y set\n"); break;
        }
    }
    return 0;
}

Опции с аргументами

Поставьте двоеточие после буквы в строке опций, чтобы указать, что опция принимает значение. "o:" означает, что -o требует аргумент.

Значение становится доступно в глобальной переменной optarg.

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "o:")) != -1) {
        if (opt == 'o') printf("output = %s\n", optarg);
    }
    return 0;
}

Объединение флагов и опций со значениями

В одной строке опций можно смешивать логические опции и опции, принимающие значения. Здесь -v является флагом, а -n принимает число.

getopt также позволяет объединять флаги, например -vn 5.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt, verbose = 0, n = 0;
    while ((opt = getopt(argc, argv, "vn:")) != -1) {
        if (opt == 'v') verbose = 1;
        else if (opt == 'n') n = atoi(optarg);
    }
    printf("verbose=%d n=%d\n", verbose, n);
    return 0;
}

Обработка неизвестных опций

Если getopt встречает опцию, отсутствующую в строке опций, он возвращает '?' и выводит ошибку (если не отключить это сообщение).

Добавьте case '?', чтобы корректно обрабатывать неверный ввод.

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "a")) != -1) {
        switch (opt) {
            case 'a': printf("a\n"); break;
            case '?': printf("unknown option\n"); break;
        }
    }
    return 0;
}

Отсутствующие обязательные аргументы

Если опция, принимающая значение, указана без этого значения, поведение getopt зависит от строки опций.

Если начать строку опций с двоеточия (":o:"), getopt будет возвращать ':' при отсутствии аргумента, чтобы Вы могли точно сообщить об этом.

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, ":f:")) != -1) {
        if (opt == 'f') printf("file=%s\n", optarg);
        else if (opt == ':') printf("option needs a value\n");
    }
    return 0;
}

optind: место остановки разбора

После завершения цикла глобальная переменная optind содержит индекс в argv первого не являющегося опцией аргумента.

Используйте её для обработки оставшихся позиционных аргументов, например имён файлов.

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "v")) != -1) { }
    for (int i = optind; i < argc; i++)
        printf("positional: %s\n", argv[i]);
    return 0;
}

Отключение сообщений getopt

По умолчанию getopt выводит собственные сообщения об ошибках в stderr. Установите глобальную переменную opterr в 0, чтобы подавить их и обрабатывать ошибки самостоятельно.

#include <stdio.h>
#include <unistd.h>

extern int opterr;

int main(int argc, char *argv[]) {
    opterr = 0;
    int opt;
    while ((opt = getopt(argc, argv, "a")) != -1) {
        if (opt == '?') printf("bad option, handled quietly\n");
    }
    return 0;
}

Определение неверной опции

Когда getopt возвращает '?', глобальная переменная optopt содержит символ ошибочной опции.

Это позволяет вывести понятное сообщение с точным указанием неверного флага.

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    while ((opt = getopt(argc, argv, "a")) != -1) {
        if (opt == '?')
            printf("Unrecognized option: -%c\n", optopt);
    }
    return 0;
}

Примечание о длинных опциях

Обычный getopt поддерживает только однобуквенные опции. Для длинных опций, таких как --verbose, системы GNU предоставляют getopt_long в <getopt.h>.

Эта функция использует тот же цикл, но дополнительно таблицу описателей длинных опций.

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    printf("getopt parses %d short options\n", argc > 1 ? argc - 1 : 0);
    return 0;
}

Быстрая проверка

Проверьте, насколько хорошо Вы поняли синтаксис строки опций getopt.

Повторение

Вы научились стандартному разбору опций с помощью getopt:

  • Выполняйте цикл, пока getopt(argc, argv, optstring) не станет равным -1, а выбор действия выполняйте с помощью switch.
  • Двоеточие после буквы означает, что опция принимает значение, доступное в optarg.
  • optind указывает на первый позиционный аргумент после этого.
  • Глобальные переменные opterr, optopt и начальное двоеточие управляют обработкой ошибок.

Часто задаваемые вопросы

Урок «getopt» бесплатный?

Да — полный текст урока «getopt» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C Academy, подпишись на CoddyKit PRO. Курс C Academy содержит 4 уроков всего.

Чему я научусь в уроке «getopt»?

Стандартный разбор параметров Ты практикуешь C Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C Academy?

Предыдущий опыт не требуется. C Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «getopt»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C Academy?

Да. Каждый урок C Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. argc и argv
  2. Разбор параметров
  3. getopt
  4. Создание инструмента CLI
← Назад к C Academy