C getopt -‹целое›

Как получить параметр -10 из аргументов командной строки - "tail -10". Функция getopt находит символ '1'. Но как мне получить доступ к строке "10"?

Если это можно сделать с помощью getopt_long, пример поможет. Спасибо.


person Ramya    schedule 16.08.2010    source источник
comment
Я подозреваю, что getopt не поддерживает многосимвольные параметры с одним тире, но я не уверен   -  person Michael Mrozek    schedule 16.08.2010


Ответы (4)


Если вы не хотите, чтобы -1 был опцией с 0 в качестве аргумента, ответ таков: вы этого не сделаете. getopt предназначен только для параметров обработки, соответствующих стандартному синтаксису параметров утилит POSIX. Для этой цели можно использовать GNU getopt_long, или вы можете просто написать свой собственный анализатор argv (это просто).

Редактировать: на самом деле я думаю, что неправильно понял, что вы хотите. Если вы хотите, чтобы - с последующим любым числом интерпретировалось как опция с этим числовым значением, я не думаю, что существует какая-либо версия getopt, которая будет работать. Вы не можете использовать особый регистр для каждого числа в качестве опции, и если вы просто скажете getopt, что все цифры являются символами опции, которые принимают аргументы, -123 будет интерпретироваться как опция -1 с аргументом 23 (что нормально , вы можете интерпретировать его оттуда), но одинокий -1 заставит следующий элемент argv получить eaten в качестве аргумента для -1, из которого трудно или невозможно восстановить.

person R.. GitHub STOP HELPING ICE    schedule 16.08.2010
comment
Я не думаю, что getopt_long это сделает, он требует -- перед аргументом - person Michael Mrozek; 16.08.2010
comment
Если я правильно помню, getopt_long включает опцию «только для длинных» (или, возможно, отдельную функцию getopt_longonly?), которая принимает либо одиночное -, либо двойное --. - person R.. GitHub STOP HELPING ICE; 16.08.2010
comment
Спасибо. У меня возникает соблазн не использовать функцию getopt. -123 через getopt это option: -1 и optarg: NULL. Мы теряем строку 23, ее нет в optarg. Могу ли я получить к нему доступ каким-либо другим способом? - person Ramya; 16.08.2010
comment
Решил не использовать getopt. Спасибо. - person Ramya; 16.08.2010

Что здесь происходит, так это то, что в языке абсолютно нет стандарта относительно правильного способа обработки параметров командной строки.

Более того, в мире Unix не было такого стандарта в течение достаточно долгого времени (думаю, есть целый раздел об этом в Справочник ненавистников Unix (ссылка в формате PDF)).

Итак, люди написали специальные механизмы обработки. В конечном итоге они превратились в общий стандарт, и getopt родился (в Bell labs). Позже мы получили GNU getopt и getopt_long. Однако это не обязательно, и некоторые программы по-прежнему управляют вещами по-своему.

Но до того, как все утряслось (а иногда и после), люди добавляли новые функции к «обычному» способу работы с параметрами всякий раз, когда это казалось хорошей идеей. Теперь можно поспорить, что tail захочет настроить количество строк чаще, чем любую другую функцию, поэтому сделать это легко и несколько нажатий клавиш< /em> приспособиться, должно быть, в то время казалось хорошей идеей...

person dmckee --- ex-moderator kitten    schedule 16.08.2010

Мне никогда не нравился getopt, поэтому я поступил как обычно и заново изобрел велосипед. Я называю свое решение argopt. Вы можете получить исходный код и страницу руководства по адресу https://github.com/colding/argopt. Я думаю, что это намного проще в использовании, чем getopt.

person colding    schedule 16.08.2010
comment
-1: хотя ваше решение может быть хорошим, это не место для его продвижения (особенно если вы заново изобретаете колесо). Кроме того, вы, кажется, единственный, кто его разрабатывает/использует. - person jmiserez; 29.03.2014

Там, где это возможно, я бы рекомендовал изменить синтаксис аргумента команды, чтобы избежать числовых аргументов, либо передав число в качестве аргумента параметра (например, -n -5), либо разрешив его только после разделителя параметров --.

В случаях, когда изменение синтаксиса аргумента невозможно, раздел ОШИБКИ справочная страница BSD getopt(3) документирует способ сделать это. Я изменил их решение, чтобы избежать optreset, который не указан в POSIX и не поддерживается glibc:

int ch;
long num;
char *numarg;

while ((ch = getopt(argc, argv, "0123456789")) != -1) {
    switch (ch) {
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
        numarg = argv[optind - 1];
        if (numarg[0] == '-' && numarg[1] == ch && numarg[2] == '\0') {
            num = '0' - ch;
        } else if ((numarg = argv[optind]) != NULL && numarg[1] == ch) {
            char *ep;
            int numoptind = optind;

            num = strtol(numarg, &ep, 10);
            if (*ep != '\0') {
                fprintf(stderr, "illegal number -- %s\n", numarg);
                return EXIT_FAILURE;
            }

            /* Advance getopt internal state to next argument. */
            while (optind == numoptind) {
                ch = getopt(argc, argv, "0123456789");
                assert(ch >= '0' && ch <= '9');
            }
        } else {
            fprintf(stderr, "number after other options -- %s\n", numarg);
            return EXIT_FAILURE;
        }
        break;

    default:
        /* Unrecognized option character.  Error printed by getopt. */
        return EXIT_FAILURE;
    }
}

Вы можете заменить getopt на getopt_long и добавить дополнительные короткие или длинные параметры по мере необходимости.

person Kevinoid    schedule 28.07.2016