использование getopt с / без опции - PullRequest
2 голосов
/ 07 марта 2019

Я пишу простой код, использующий параметр *argv[].Я хотел бы знать, могу ли я использовать функцию getopt() для следующего намерения.

./myprogram -a PATH
./myprogram PATH

Программа может принимать просто PATH (например, /usr/tmp) или использовать параметр -a вдополнение к PATH.Может ли getopt() использоваться для этого состояния?Если можно, то как?

Ответы [ 2 ]

3 голосов
/ 07 марта 2019

Программа может принимать просто PATH (например, /usr/tmp) или использовать опцию в дополнение к PATH.Можно ли использовать getopt() для этого состояния?Если можете, то как?

Конечно.Я не уверен, где вы вообще видите потенциальную проблему, если только вы не понимаете различия POSIX и getopt() между options и arguments .Они связаны, но совсем не одно и то же.

getopt() подходит для случая, когда на самом деле не заданы никакие опции, и дает вам доступ к неопционным аргументам, таким как PATH Похоже, для вас, независимо от того, сколько опций указано.Обычная модель использования - вызывать getopt() в цикле, пока он не вернет -1, чтобы указать, что больше нет доступных опций из командной строки.На каждом шаге глобальная переменная optind предоставляет индекс следующего элемента argv для обработки, а после getopt() (первый) возвращает -1, optind предоставляет индекс первого неопционального аргумента.В вашем случае это будет то место, где вы ожидаете найти PATH.

int main(int argc, char *argv[]) {
    const char options[] = "a";
    _Bool have_a = 0;
    char *the_path;
    int opt;

    do {
        switch(opt = getopt(argc, argv, options)) {
            case -1:
                the_path = argv[optind];
                // NOTE: the_path will now be null if no path was specified,
                //       and you can recognize the presence of additional,
                //       unexpected arguments by comparing optind to argc
                break;
            case 'a':
                have_a = 1;
                break;
            case '?':
                // handle invalid option ...
                break;
            default:
                // should not happen ...
                assert(0);
                break;
        }
    } while (opt >= 0);
}
2 голосов
/ 07 марта 2019

Использование строки опций "a" позволяет аргументу -a действовать как флаг.
optind помогает обнаружить наличие только одного дополнительного аргумента.
Программа может быть выполнена как ./program -a path или ./program path

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

int main(int argc, char **argv)
{
    char op = ' ';//default value
    int opt;

    while ((opt = getopt(argc, argv, "a")) != -1)//optstring allows for -a argument
    {
        switch (opt)
        {
        case 'a':
            op = 'a';//found option, set op
            break;
        default:
            fprintf(stderr, "%s: unknown option %c\n", argv[0], optopt);
            return 1;
        }
    }
    if ( optind + 1 != argc)//one argument allowed besides optstring values
    {
        fprintf(stderr, "Usage: %s [-a] PATH\n", argv[0]);
        return 1;
    }

    printf("%s %c\n", argv[optind], op);
    return 0;
}
...