Skrive printf-lignende funksjoner
Variable argumenter
Skrive printf-lignende funksjoner er en gratis leksjon i C Academy på CoddyKit. Dette er leksjon 2 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i C Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i C Academy inneholder totalt 4 leksjoner.
Funksjoner som tar en formatstreng
Den kraftigste bruken av variadiske argumenter er å bygge funksjoner i printf-stil som tolker en formatstreng.
Formatet forteller funksjonen hvor mange argumenter som følger, og hvilken type hvert av dem har.
#include <stdio.h>
#include <stdarg.h>
void myprint(const char *fmt, ...) {
printf("format was: %s\n", fmt);
}
int main(void) {
myprint("%d items\n", 5);
return 0;
}Gå gjennom formatstrengen
Les formatet tegn for tegn. Når De ser et %, er det neste tegnet en konverteringsspesifikator som forteller hvilken type som skal leses.
Alt annet skrives ut bokstavelig.
#include <stdio.h>
#include <stdarg.h>
void scan(const char *fmt) {
for (const char *p = fmt; *p; p++) {
if (*p == '%') printf("[spec:%c]", *(p+1));
else putchar(*p);
}
putchar('\n');
}
int main(void) {
scan("x=%d y=%s");
return 0;
}Lese riktig type
Når spesifikatoren er %d, leser De en int. For %s leser De en char *. Formatet må stemme nøyaktig med de faktiske argumentene.
#include <stdio.h>
#include <stdarg.h>
void mini(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
for (const char *p = fmt; *p; p++) {
if (*p == '%' && *(p+1) == 'd') {
printf("%d", va_arg(args, int));
p++;
} else putchar(*p);
}
va_end(args);
}
int main(void) {
mini("count=%d\n", 42);
return 0;
}Håndtere flere spesifikatorer
Utvid skanningen slik at den håndterer flere konverteringer. Legg til tilfeller for %d, %s og %c, og les riktig type hver gang.
#include <stdio.h>
#include <stdarg.h>
void fmt_print(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
for (const char *p = fmt; *p; p++) {
if (*p != '%') { putchar(*p); continue; }
p++;
if (*p == 'd') printf("%d", va_arg(args, int));
else if (*p == 's') printf("%s", va_arg(args, char *));
else if (*p == 'c') putchar(va_arg(args, int));
}
va_end(args);
}
int main(void) {
fmt_print("%s is %d\n", "age", 30);
return 0;
}Escape prosenttegnet
Virkelige formatfunksjoner behandler %% som et bokstavelig prosenttegn. Legg til et tilfelle slik at brukerne kan skrive ut et faktisk %.
#include <stdio.h>
#include <stdarg.h>
void fp(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
for (const char *p = fmt; *p; p++) {
if (*p == '%') {
p++;
if (*p == '%') putchar('%');
else if (*p == 'd') printf("%d", va_arg(args, int));
} else putchar(*p);
}
va_end(args);
}
int main(void) {
fp("%d%% done\n", 75);
return 0;
}Videreformidle til vprintf
Ofte ønsker De ikke å implementere formateringen på nytt. Standardbiblioteket tilbyr vprintf, som tar en va_list direkte.
Wrapperen Deres sender ganske enkelt argumentene videre.
#include <stdio.h>
#include <stdarg.h>
void logline(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
int main(void) {
logline("value = %d, name = %s\n", 7, "box");
return 0;
}Legge til et prefiks
vprintf-metoden gjør det enkelt å legge til funksjonalitet rundt standardformateringen, for eksempel å skrive ut en etikett før hver melding.
#include <stdio.h>
#include <stdarg.h>
void info(const char *fmt, ...) {
printf("[INFO] ");
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
int main(void) {
info("server started on port %d\n", 8080);
return 0;
}Skrive til en buffer med vsnprintf
Hvis De vil formatere til en streng i stedet for å skrive den ut, bruker De vsnprintf(buf, size, fmt, args).
Den er begrenset av size, noe som hindrer overflyt, og avslutter alltid strengen med null-tegnet.
#include <stdio.h>
#include <stdarg.h>
void format_into(char *buf, size_t n, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
vsnprintf(buf, n, fmt, args);
va_end(args);
}
int main(void) {
char out[64];
format_into(out, sizeof(out), "id-%d", 123);
printf("%s\n", out);
return 0;
}Returnere en lengde
vsnprintf returnerer antallet tegn som ville ha blitt skrevet. De kan bruke dette til å oppdage avkorting eller til å beregne riktig bufferstørrelse.
#include <stdio.h>
#include <stdarg.h>
int build(char *buf, size_t n, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
int len = vsnprintf(buf, n, fmt, args);
va_end(args);
return len;
}
int main(void) {
char b[10];
int needed = build(b, sizeof(b), "%d-%d", 11, 22);
printf("%s (needed %d)\n", b, needed);
return 0;
}Velge fremgangsmåte
Det finnes to strategier: analyser formatet selv for full kontroll, eller send det videre til vprintf/vsnprintf for korrekthet og mindre kode.
For det meste av kode i praksis er videreformidling det tryggeste og enkleste valget.
#include <stdio.h>
#include <stdarg.h>
void say(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
vfprintf(stdout, fmt, args);
va_end(args);
}
int main(void) {
say("%s = %.1f\n", "pi", 3.14);
return 0;
}Uoverensstemmelser gir udefinert oppførsel
Hvis formatstrengen angir en type som ikke stemmer med det faktiske argumentet, er oppførselen udefinert.
printf("%d", "text") kan krasje. Sørg alltid for at formatet og argumentene er synkronisert.
#include <stdio.h>
int main(void) {
int n = 5;
printf("%d\n", n);
return 0;
}Rask kontroll
Test forståelsen Deres av wrappere i printf-stil.
Oppsummering
De har lært å bygge printf-lignende funksjoner:
- Ta en formatstreng som navngitt parameter, etterfulgt av
.... - Analyser enten
%-spesifikatorene selv og les samsvarende typer, eller - videreformidle
va_listtil vprintf / vsnprintf for trygg og korrekt formatering. - Sørg for at formatet og argumenttypene stemmer overens, slik at De unngår udefinert oppførsel.
Lær deg C med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 39
- Leksjoner
- 144
Ofte stilte spørsmål
Er leksjonen «Skrive printf-lignende funksjoner» gratis?
Ja – hele teksten i «Skrive printf-lignende funksjoner» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av C Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i C Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Skrive printf-lignende funksjoner»?
Variable argumenter Du øver på C Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med C Academy?
Ingen tidligere erfaring er nødvendig. C Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.
Hvor lang tid tar leksjonen «Skrive printf-lignende funksjoner»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne C Academy-leksjonen?
Ja. Alle C Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- stdarg-makroene
- Skrive printf-lignende funksjoner
- Utfordringer med typesikkerhet
- Praktiske eksempler