Getopt() в C не читает аргументы опций

Я набираю программу, и она принимает три параметра командной строки: s, f и c
Поскольку мне сказали использовать функцию getopt() для их получения, я изучил ее.

Три варианта делают следующее:
s - это просто опция "без логов", мне нужно только проверить есть она или нет
f - это параметр пути к файлу, за которым следует его аргумент (я решил, что лучше взять его как массив символов, а затем использовать с ним fopen)
c - это еще один массив символов, который принимает аргумент после себя

Я обращаюсь к вам после 2 часов попыток правильно настроить эти параметры с помощью функции и не смог.

На удивление мало документации для getopt(), я не смог найти хороший пример, где код объясняется построчно, но, тем не менее, это то, к чему я пришел после прочтения страницы geeksforgeeks и нескольких страниц документации GNU. относительно этого:

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

int main(int argc, char **argv)
{
    int opt;
    char *cli_input_s = NULL;
    char *cli_input_f = NULL;
    char *cli_input_c = NULL;

    while ((opt = getopt(argc, argv, "fc:s")) != -1)
    {
        switch (opt)
        {
            case 's':
                printf("Program is executing without logs.\n");
                break;
            case 'f':
                strcpy(cli_input_f, argv[optind]);
                break;
            case 'c':
                strcpy(cli_input_c, argv[optind]);
                break;
            case '?':
                printf("The program has encountered an unknown argument, aborting.");
                break;
            default:
                printf("I don't know what exactly is going on but...");
                break;
        }
    }

    printf("%d \n", argc);
    printf("%s \n", cli_input_s);
    printf("%s \n", cli_input_f);
    printf("%s \n", cli_input_c);
}

Я использую argv[optind] вместо optarg, потому что он не записывает правильную вещь в аргументы. До сих пор я пытался запустить следующий ввод CLI:
имя файла -s -f abc -c abc

В результате я получаю: «Программа выполняется без журналов». и все.
В какой-то момент мне действительно удалось получить все printf в конце для... печати.
Но теперь это единственное, что печатает, и у меня совсем нет идей.
Кроме того, компиляция занимает удивительно много времени (несколько секунд). Я использую CLion IDE и компилятор MinGW в комплекте.

Что именно я делаю неправильно и почему я не могу правильно получить аргументы CLI?

Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Строка опций "fc:s" говорит, что только -c может иметь аргумент. Вам нужен символ аргумента : для каждой опции, которая может принимать аргумент.

Таким образом, ваша строка должна быть "f:c:s", если вы хотите, чтобы опция -f также имела аргумент.


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

Возьмем, к примеру

strcpy(cli_input_f, argv[optind]);

Указатель cli_input_f является нулевым указателем. Это никуда не указывает. И все же вы используете его как место назначения для строки. Это невозможно.

У вас должен быть указатель на строку, достаточно длинную, чтобы содержать исходную строку, включая завершающий ноль в конце.

Я рекомендую вам просто изменить ваши переменные с указателей на массивы достаточного размера:

char cli_input_f[256] = { 0 };  // Initialize all elements to the string null-terminator

Спасибо за разъяснение, я действительно не понял этого. Я все еще получаю тот же результат, хотя.

DarkRemino 06.05.2023 11:05

@DarkRemino Я обнаружил гораздо более серьезную ошибку, которая, вероятно, приводит к сбоям.

Some programmer dude 06.05.2023 11:14

Спасибо за ответ! На самом деле я снова посмотрел на документацию GNU и, как ни странно, они инициализируют массив char значением NULL и впоследствии присваивают ему переменную optarg. Я попытался сделать то, что вы рекомендовали, и он все еще делает то же самое.

DarkRemino 06.05.2023 11:40

в итоге я просто присвоил cli_input_f значение null и написал 'cli_input_f = optarg;' Я не совсем уверен, почему, но теперь это работает. @Какой-то программист, чувак

DarkRemino 06.05.2023 11:45

@DarkRemino Нет гарантии, что у каждого аргумента будет отдельный optarg. Это может быть один статический буфер, который используется повторно. Вам нужно скопировать его в свой собственный массив.

Some programmer dude 06.05.2023 11:48

@DarkRemino И если вы не знаете, почему вы не можете использовать нулевые указатели в strcpy, сделайте несколько шагов назад и обновите главы и разделы, посвященные указателям, в учебных материалах для начинающих.

Some programmer dude 06.05.2023 11:49

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