Praktyczne przykłady
Funkcja logująca
Praktyczne przykłady to bezpłatna lekcja C Academy na CoddyKit. To lekcja 4 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.
Funkcja logująca
Logger to doskonałe praktyczne zastosowanie argumentów wariadycznych. Chcemy wywoływać log_msg("user %s scored %d", name, score) tak jak printf.
W tej lekcji zbudujesz małe, przydatne narzędzie do logowania.
#include <stdio.h>
#include <stdarg.h>
void log_msg(const char *fmt, ...) {
va_list a; va_start(a, fmt);
vprintf(fmt, a);
va_end(a);
printf("\n");
}
int main(void) {
log_msg("user %s scored %d", "Ann", 90);
return 0;
}Dodawanie poziomu ważności
Rzeczywiste loggery oznaczają komunikaty poziomem, takim jak INFO lub ERROR. Dodaj stały parametr przed napisem formatującym, który określa poziom.
#include <stdio.h>
#include <stdarg.h>
void logf(const char *level, const char *fmt, ...) {
printf("[%s] ", level);
va_list a; va_start(a, fmt);
vprintf(fmt, a);
va_end(a);
printf("\n");
}
int main(void) {
logf("INFO", "started with %d workers", 4);
return 0;
}Dodawanie znaczników czasu do komunikatów
Każdy wiersz można wzbogacić o dodatkowy kontekst przed przekazaniem formatu dalej. W tym przykładzie jako zamiennika znacznika czasu użyjemy fikcyjnego licznika umieszczanego na początku.
#include <stdio.h>
#include <stdarg.h>
static int line_no = 0;
void logf(const char *fmt, ...) {
printf("#%d ", ++line_no);
va_list a; va_start(a, fmt);
vprintf(fmt, a);
va_end(a);
printf("\n");
}
int main(void) {
logf("first %s", "event");
logf("value %d", 7);
return 0;
}Logowanie do stderr
Błędy i informacje diagnostyczne zwykle trafiają do stderr. Użyj vfprintf(stderr, fmt, args), aby dane dziennika nie mieszały się ze standardowym wyjściem programu.
#include <stdio.h>
#include <stdarg.h>
void err(const char *fmt, ...) {
fprintf(stderr, "ERROR: ");
va_list a; va_start(a, fmt);
vfprintf(stderr, fmt, a);
va_end(a);
fprintf(stderr, "\n");
}
int main(void) {
err("failed to open %s", "data.txt");
return 0;
}Warunkowe logowanie
Próg szczegółowości pozwala wyciszyć komunikaty o niskim priorytecie. Przed wypisaniem porównaj poziom komunikatu ze skonfigurowanym minimum.
#include <stdio.h>
#include <stdarg.h>
static int min_level = 2;
void logf(int level, const char *fmt, ...) {
if (level < min_level) return;
va_list a; va_start(a, fmt);
vprintf(fmt, a);
va_end(a);
printf("\n");
}
int main(void) {
logf(1, "debug hidden");
logf(3, "important %d", 42);
return 0;
}Budowanie napisu komunikatu
Czasami sformatowany tekst powinien trafić do bufora, a nie na wyjście. Użyj vsnprintf, aby go utworzyć, a następnie zdecyduj, co z nim zrobić.
#include <stdio.h>
#include <stdarg.h>
void capture(const char *fmt, ...) {
char buf[128];
va_list a; va_start(a, fmt);
vsnprintf(buf, sizeof(buf), fmt, a);
va_end(a);
printf("captured: %s\n", buf);
}
int main(void) {
capture("id=%d name=%s", 5, "box");
return 0;
}Wariadyczna funkcja max
Argumenty wariadyczne sprawdzają się również w pomocniczych funkcjach matematycznych. Oto funkcja, która zwraca największą spośród kilku liczb całkowitych, korzystając z parametru z liczbą argumentów.
#include <stdio.h>
#include <stdarg.h>
int max_of(int count, ...) {
va_list a; va_start(a, count);
int best = va_arg(a, int);
for (int i = 1; i < count; i++) {
int v = va_arg(a, int);
if (v > best) best = v;
}
va_end(a);
return best;
}
int main(void) {
printf("%d\n", max_of(4, 3, 9, 2, 7));
return 0;
}Łączenie napisów
Korzystając z wartownika NULL, można połączyć dowolną liczbę napisów w jeden bufor.
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
void join(char *out, const char *first, ...) {
out[0] = '\0';
va_list a; va_start(a, first);
const char *s = first;
while (s) { strcat(out, s); s = va_arg(a, const char *); }
va_end(a);
}
int main(void) {
char buf[64];
join(buf, "a", "b", "c", (char *)NULL);
printf("%s\n", buf);
return 0;
}Zliczanie liczb całkowitych wariadycznych
Licznik oparty na wartowniku pokazuje elastyczność tego schematu. Zliczamy wartości aż do napotkania kończącego 0.
#include <stdio.h>
#include <stdarg.h>
int count_until_zero(int first, ...) {
va_list a; va_start(a, first);
int n = 0, v = first;
while (v != 0) { n++; v = va_arg(a, int); }
va_end(a);
return n;
}
int main(void) {
printf("%d\n", count_until_zero(5, 6, 7, 0));
return 0;
}Opakowywanie w makro
Popularnym sposobem jest makro, które automatycznie uzupełnia poziom, dzięki czemu wywołujący musi pisać mniej. Makro przekazuje argumenty do właściwej funkcji wariadycznej.
#include <stdio.h>
#include <stdarg.h>
void real_log(const char *lvl, const char *fmt, ...) {
printf("[%s] ", lvl);
va_list a; va_start(a, fmt);
vprintf(fmt, a);
va_end(a);
printf("\n");
}
#define LOG_INFO(...) real_log("INFO", __VA_ARGS__)
int main(void) {
LOG_INFO("ready in %d ms", 50);
return 0;
}Korzystanie z loggera
Oto kompletny mini-logger łączący poziom i licznik znaczników czasu, gotowy do dodania do programu.
#include <stdio.h>
#include <stdarg.h>
static int seq = 0;
void mylog(const char *lvl, const char *fmt, ...) {
printf("%04d [%s] ", ++seq, lvl);
va_list a; va_start(a, fmt);
vprintf(fmt, a);
va_end(a);
printf("\n");
}
int main(void) {
mylog("INFO", "boot ok");
mylog("WARN", "low memory: %d MB", 64);
return 0;
}Szybkie sprawdzenie
Sprawdź swoją wiedzę na temat projektowania logowania wariadycznego.
Podsumowanie
Zbudowałeś praktyczne narzędzia wariadyczne:
- Logger, który przekazuje swój format do
vprintf/vfprintf. - Dodawanie poziomów, liczników, wyjścia stderr i filtrowania warunkowego.
- Używanie
vsnprintfdo zapisywania komunikatów w buforach. - Pomocnicze funkcje oparte na wartownikach oraz wygodne opakowanie w postaci makra.
Często zadawane pytania
Czy lekcja „Praktyczne przykłady” jest bezpłatna?
Tak — pełny tekst „Praktyczne przykłady” 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 „Praktyczne przykłady”?
Funkcja logująca Ć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 4 z 4.
Ile czasu zajmuje lekcja „Praktyczne przykłady”?
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
- Makra stdarg
- Pisanie funkcji podobnych do printf
- Problemy z bezpieczeństwem typów
- Praktyczne przykłady