0Pricing
C Academy · Lekcja

Parsowanie opcji

Obsługa flag

Parsowanie opcji to bezpłatna lekcja C Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C Academy zawiera 4 lekcji w sumie.

Opcje a argumenty pozycyjne

Argumenty wiersza poleceń występują w dwóch postaciach. Argumenty pozycyjne to wartości takie jak nazwy plików. Opcje (nazywane także flagami) zaczynają się od łącznika, na przykład -v lub --help.

W tej lekcji pokazano, jak ręcznie wykrywać i obsługiwać flagi.

#include <stdio.h>

int main(int argc, char *argv[]) {
    for (int i = 1; i < argc; i++) {
        if (argv[i][0] == '-')
            printf("option: %s\n", argv[i]);
        else
            printf("value:  %s\n", argv[i]);
    }
    return 0;
}

Wykrywanie flagi

Aby sprawdzić konkretną flagę, należy porównać każdy argument za pomocą strcmp.

W tym przykładzie ustawiamy wartość logiczną po napotkaniu -v, oznaczającego tryb szczegółowy.

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

int main(int argc, char *argv[]) {
    int verbose = 0;
    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "-v") == 0)
            verbose = 1;
    }
    printf("verbose = %d\n", verbose);
    return 0;
}

Obsługa długich opcji

Wiele narzędzi akceptuje zarówno krótką formę (-h), jak i długą formę (--help).

Należy sprawdzić oba zapisy za pomocą dwóch porównań połączonych operatorem ||.

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

int main(int argc, char *argv[]) {
    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "-h") == 0 ||
            strcmp(argv[i], "--help") == 0) {
            printf("Usage: prog [options]\n");
            return 0;
        }
    }
    printf("No help requested\n");
    return 0;
}

Opcje przyjmujące wartość

Niektóre flagi wymagają argumentu, na przykład -o output.txt. Po napotkaniu takiej flagi jej wartością jest następny element argv.

Należy zwiększyć indeks pętli i sprawdzić, czy nie wykracza on poza koniec tablicy.

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

int main(int argc, char *argv[]) {
    const char *output = "default.txt";
    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "-o") == 0 && i + 1 < argc) {
            output = argv[++i];
        }
    }
    printf("Output file: %s\n", output);
    return 0;
}

Obsługa brakującej wartości

Jeśli -o jest ostatnim argumentem, nie ma po nim żadnej wartości. Odczytanie argv[i+1] wykraczałoby poza zakres.

Zawsze należy sprawdzić i + 1 < argc przed pobraniem następnego tokenu, a w przeciwnym razie zgłosić błąd.

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

int main(int argc, char *argv[]) {
    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "-n") == 0) {
            if (i + 1 >= argc) {
                printf("Error: -n needs a value\n");
                return 1;
            }
            printf("n = %s\n", argv[++i]);
        }
    }
    return 0;
}

Łączenie flag logicznych i wartości

Realistyczny analizator śledzi jednocześnie kilka flag: niektóre logiczne, a inne przyjmujące wartości. Należy użyć osobnych zmiennych dla każdego ustawienia.

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

int main(int argc, char *argv[]) {
    int verbose = 0;
    const char *name = "world";
    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "-v") == 0) verbose = 1;
        else if (strcmp(argv[i], "-name") == 0 && i+1 < argc) name = argv[++i];
    }
    if (verbose) printf("verbose mode\n");
    printf("Hello, %s\n", name);
    return 0;
}

Rozpoznawanie końca opcji

Zgodnie z konwencją pojedyncze -- oznacza koniec opcji. Wszystko, co znajduje się za nim, jest traktowane jako argument pozycyjny, nawet jeśli zaczyna się od łącznika.

Pozwala to przekazywać nazwy plików zaczynające się od -.

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

int main(int argc, char *argv[]) {
    int opts_done = 0;
    for (int i = 1; i < argc; i++) {
        if (!opts_done && strcmp(argv[i], "--") == 0) {
            opts_done = 1;
            continue;
        }
        printf("%s: %s\n", opts_done ? "value" : "token", argv[i]);
    }
    return 0;
}

Zbieranie argumentów pozycyjnych

Często potrzebne są flagi oraz lista plików. Należy pominąć rozpoznane opcje, a resztę zapisać jako argumenty pozycyjne.

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

int main(int argc, char *argv[]) {
    for (int i = 1; i < argc; i++) {
        if (argv[i][0] == '-') continue;
        printf("file: %s\n", argv[i]);
    }
    return 0;
}

Obsługa nieznanych opcji

Przyjazne narzędzie zgłasza nieznane flagi zamiast je po cichu ignorować. Należy porównać je ze znanymi opcjami, a w przeciwnym razie wyświetlić ostrzeżenie.

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

int main(int argc, char *argv[]) {
    for (int i = 1; i < argc; i++) {
        if (argv[i][0] != '-') continue;
        if (strcmp(argv[i], "-v") != 0)
            printf("Unknown option: %s\n", argv[i]);
    }
    return 0;
}

Konwertowanie wartości opcji

Wartości opcji są przekazywane jako łańcuchy. Wartości liczbowe należy konwertować za pomocą strtol, które zgłasza również błędy analizy za pomocą wskaźnika końca.

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

int main(int argc, char *argv[]) {
    int count = 1;
    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "-c") == 0 && i+1 < argc)
            count = (int) strtol(argv[++i], NULL, 10);
    }
    printf("count = %d\n", count);
    return 0;
}

Dlaczego warto użyć rzeczywistego analizatora

Ręczne analizowanie działa, ale staje się nieczytelne przy łączonych krótkich flagach (-vf), składni z = (--name=foo) oraz regułach kolejności.

Standardowa funkcja getopt, omawiana w następnej części, obsługuje te konwencje za Państwa.

#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("Parsed %d tokens manually\n", argc - 1);
    return 0;
}

Szybkie sprawdzenie

Sprawdź swoją wiedzę na temat problemów związanych z analizowaniem opcji.

Podsumowanie

Dowiedzieli się Państwo, jak ręcznie analizować opcje:

  • Flagi zaczynają się od -; należy porównywać je za pomocą strcmp.
  • Krótkie i długie formy można obsłużyć za pomocą ||.
  • Opcje przyjmujące wartości pobierają następny token — należy zabezpieczyć się warunkiem i + 1 < argc.
  • -- kończy analizowanie opcji; nieznane flagi należy zgłaszać, a wartości liczbowe konwertować za pomocą strtol.

Często zadawane pytania

Czy lekcja „Parsowanie opcji” jest bezpłatna?

Tak — pełny tekst „Parsowanie opcji” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C Academy, przejdź na CoddyKit PRO. Kurs C Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Parsowanie opcji”?

Obsługa flag Ćwiczysz C Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C Academy?

Nie wymagamy żadnego doświadczenia. C Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Parsowanie opcji”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C Academy?

Tak. Każda lekcja C Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. argc i argv
  2. Parsowanie opcji
  3. getopt
  4. Budowanie narzędzia CLI
← Powrót do C Academy