C getopt - <integer> - PullRequest
       4

C getopt - <integer>

3 голосов
/ 16 августа 2010

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

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

Ответы [ 4 ]

3 голосов
/ 16 августа 2010

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

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

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

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

3 голосов
/ 16 августа 2010

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

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

0 голосов
/ 28 июля 2016

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

Для случаев, когда изменение синтаксиса аргумента невозможно, в разделе BUGS справочной страницы 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 и при необходимости добавьте дополнительные короткие или длинные опции.

0 голосов
/ 16 августа 2010

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

...