Ce face snprintf și sprintf
snprintf construiește un șir în memorie, cu același șablon ca printf. Scrie cel mult n - 1 caractere și pune mereu '\0' la final (dacă n > 0), deci nu depășește tabloul. A apărut în C99.
Valoarea returnată este lungimea pe care ar fi avut-o textul complet. Dacă ea este mai mare sau egală cu n, textul a fost tăiat. Un truc des folosit: snprintf(NULL, 0, ...) nu scrie nimic, dar spune câți octeți îți trebuie, ca să aloci exact atât cu malloc.
sprintf (C89) face același lucru fără limită de dimensiune: dacă rezultatul nu încape, scrie peste memoria de după tablou. Preferă snprintf. Operația inversă, citirea valorilor dintr-un șir, o face sscanf.
Parametri
| Parametru | Descriere |
|---|---|
s |
Tabloul în care se scrie rezultatul (poate fi NULL dacă n este 0). |
n |
Dimensiunea tabloului, inclusiv locul pentru '\0'. |
format, ... |
Șablonul și valorile, ca la printf. |
Ce returnează
Numărul de caractere al textului complet (fără '\0'), chiar dacă a fost tăiat; o valoare negativă la eroare de formatare.
Exemple
Exemplul 1: Un nume de fișier construit din date
%02d pune zerouri în față, ca numele să se ordoneze corect. sizeof nume este dimensiunea tabloului.
#include <stdio.h>
int main(void) {
char nume[40];
int an = 2026, luna = 3, zi = 7;
snprintf(nume, sizeof nume, "raport-%d-%02d-%02d.csv", an, luna, zi);
printf("Fișier: %s\n", nume);
return 0;
}
Rezultat
Fișier: raport-2026-03-07.csv
Exemplul 2: Detectarea textului tăiat
Tabloul are doar 12 octeți. snprintf scrie 11 caractere și '\0', dar returnează 25, lungimea textului complet. Comparația cu dimensiunea arată că textul a fost tăiat.
#include <stdio.h>
int main(void) {
char eticheta[12];
int necesar = snprintf(eticheta, sizeof eticheta, "Client: %s, %d lei", "Ana Pop", 1250);
printf("Scris: \"%s\"\n", eticheta);
printf("Lungime necesară: %d\n", necesar);
if (necesar >= (int)sizeof eticheta) {
printf("Textul a fost tăiat.\n");
}
return 0;
}
Rezultat
Scris: "Client: Ana"
Lungime necesară: 25
Textul a fost tăiat.
Exemplul 3: Alocare exactă cu snprintf(NULL, 0, …)
Primul apel doar măsoară. Alocăm lungimea plus un octet pentru '\0', apoi formatăm de-adevăratelea. sscanf face drumul invers și scoate numerele din text.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *oras = "Iași";
int lungime = snprintf(NULL, 0, "%s: %d locuitori", oras, 271692);
char *text = malloc((size_t)lungime + 1);
if (text == NULL) {
return 0;
}
snprintf(text, (size_t)lungime + 1, "%s: %d locuitori", oras, 271692);
printf("%s (%d octeți)\n", text, lungime);
free(text);
int zi, luna, an;
if (sscanf("15.06.2026", "%d.%d.%d", &zi, &luna, &an) == 3) {
printf("zi=%d luna=%d an=%d\n", zi, luna, an);
}
return 0;
}
Rezultat
Iași: 271692 locuitori (23 octeți)
zi=15 luna=6 an=2026
Greșeli frecvente
- Folosești
sprintfcu date venite din afară. Dacă textul e mai lung decât tabloul, se scrie peste altă memorie (depășire de buffer, o cauză clasică de breșe de securitate). - Crezi că valoarea returnată este numărul de caractere scrise efectiv. Este lungimea textului complet; dacă e
>= n, textul a fost tăiat. - Transmiți
sizeofal unui pointer în loc de dimensiunea tabloului:sizeof ppentruchar *p = malloc(100)este 8, nu 100.
Comenzi înrudite
printf: Afișează text formatat pe ecran: un șablon cu specificatori (%d, %s, %.2f) completați cu valorile primite după el.Specificatori de format (%d, %f, %s): Ce înseamnă %d, %u, %f, %e, %s, %c, %x, %zu și cum controlezi lățimea, zecimalele și alinierea în printf.scanf: Citește valori de la tastatură după un șablon (%d, %lf, %s) și le scrie la adresele primite; returnează câte valori a citit.malloc: Cere sistemului un bloc de memorie de mărimea dată, în timpul rulării, și returnează adresa lui sau NULL dacă nu reușește.strcpy, strncpy și strdup: Copiază un șir C într-un alt tablou (strcpy, strncpy) sau într-o zonă nouă alocată cu malloc (strdup).