Как считать argc в C

У меня проблема с получением правильного количества параметров:

    while((opt=getopt(argc, argv, ":a:c:SL")) != -1)

Если я запускаю скрипт: ./script -a ok -c 1 -S -L переменная argc равна 7

Проблема в том, когда я хочу запустить скрипт как ./script -a ok -c 1 -SS -L переменная argc равна 7, но это должно быть 8 причин (SS (или LL/CC) должно быть засчитано как два).

3 ответа

Решение

Это звучит как проблема XY. Я подозреваю, что причина, по которой вы хотите посчитать количество аргументов, которые getopt процессы - это доступ к любым следующим аргументам, которые не являются опциями.

Страница man указывает на решение:

Если больше нет опционных символов, getopt() возвращает -1. затем optind это индекс в argv из первых argv-элемент, который не вариант.

Однажды ваш while цикл завершается, вы можете сделать следующее:

int i;
for (i = optind; i < argc; i++) {
    printf("non-option arument: %s\n", argv[i]);
}

Поочередно, вы можете двигаться вверх argv так что он указывает на первый не опциональный аргумент и декремент argc соответственно. Затем вы можете начать индексирование с 0:

argc -= optind;
argv += optind;
int i;
for (i = 0; i < argc; i++) {
    printf("non-option arument: %s\n", argv[i]);
}

Вы не можете сделать это. Если это так, то вам нужно разобрать аргумент самостоятельно и понять его самостоятельно. Большинство стандартных команд работают таким образом.

Вы не можете изменить то, что считает argc и как он считает. Чтобы получить правильное количество отсчетов без getopt Вы можете просто посчитать argv самостоятельно.

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

С getopt Вы можете правильно получить все варианты. Ты можешь получить -SSS и тогда вы можете решить, каково поведение в соответствии с этим вариантом.

Вместо написания собственной логики подсчета или обработки опций синтаксического анализатора или чего-то подобного, есть хороший и более понятный способ добиться того же (см. Комментарий xtofl).

Простая идея состоит в том, чтобы использовать параметры нескольких символов, чтобы -S 3 что означало бы, что -SSS, Таким образом, вы всегда можете легко разобрать его, а также получить представление о том, какое поведение пользователь ожидает от программы, указанной в параметрах. 1

Небольшой пример:

static const char help[] =
    "  -h       help help all this\n"
    "  -m times multiply by times\n"
    "  -s size  shift by size\n"
    "  -a add   addition by add\n"
    ;

int opt;
while ((opt = getopt(argc, argv, "hm:s:a:")) != -1)
{
    switch (opt)
    {
    case 'h':
        puts(help);
        return EXIT_SUCCESS;
    case 'm':
        opm = atoi(optarg);
        break;
    case 's':
        ops = atoi(optarg);
        break;
    case 'a':
        opa = atoi(optarg);
        break;
    default:
        return EXIT_FAILURE;
    }

1. Это вопрос мнения, какой из них используется. Оба одинаково могут использоваться в разных утилитах. Базовый способ интерпретации вещи немного меняется. Кроме того, они в основном одинаковы.

getopt будет интерпретировать -SS как два S опции. Точно так же это будет интерпретировать -SL как S вариант следовал L вариант. Это также будет интерпретировать как -c2 а также -c 2 как c вариант с аргументом 2даже если первый аргумент представляет собой один аргумент командной строки, а второй - два аргумента.

argc сообщает, сколько аргументов команды lime было передано, но не может сказать, сколько параметров будет проанализировано. Это не должно быть проблемой, хотя.

Другие вопросы по тегам