Использование getopt с/без опции

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

./myprogram -a PATH
./myprogram PATH

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
903
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

The program can either take merely PATH (e.g. /usr/tmp) or take option in addition to PATH. Can getopt() be used for this state? If can, how?

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

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);
}

Сэр, что вы имеете в виду, говоря Certainly. I'm not sure where you even see a potential issue, unless its that you don't appreciate POSIX's and getopt()'s distinction between options and arguments. They are related, but not at all the same thing.? Я не знаю, есть ли разница между параметрами и аргументами POSIX и getopt(). Разве я не должен использовать getopt() для такого случая?

snr 07.03.2019 15:19

@snr, вы можете полностью использовать getopt() для своего случая, как действительно демонстрирует мой пример кода. Я просто рискнул предположить, почему вы не уверены в этом, и похоже, что я был прав. Опции, аргументы для опций и аргументы без опций передаются вашей программе через в виде ее аргументов, но опции сами по себе не являются аргументами, и они не обязательно отображаются на аргументы способом 1:1. Параметры соответствуют и представлены отдельными буквами параметров, а не целыми аргументами, и getopt() может отличить их от аргументов, не являющихся параметрами.

John Bollinger 07.03.2019 15:28

Использование optstring "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;
}

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

John Bollinger 07.03.2019 15:09

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