Ce face scanf
scanf citește din intrarea standard (stdin) și transformă textul în valori. Șablonul seamănă cu cel de la printf, dar după el trimiți adresele variabilelor, cu &: scanf("%d", &varsta). Excepție fac tablourile de caractere, al căror nume este deja o adresă.
Specificatorii numerici și %s sar peste spațiile albe (spațiu, tab, rând nou) dinaintea valorii. %s citește un singur cuvânt, până la primul spațiu. Pune mereu o lățime maximă, cu unu mai mică decât tabloul: %19s pentru char nume[20], altfel un cuvânt lung scrie peste memoria de după tablou.
Valoarea returnată este numărul de câmpuri citite cu succes, sau EOF dacă intrarea s-a terminat înainte de primul câmp. Verifică-o mereu: dacă utilizatorul scrie litere în loc de un număr, scanf se oprește, returnează 0 și lasă textul greșit în stdin. Pentru citiri robuste, mulți programatori citesc rândul cu fgets și îl analizează apoi cu sscanf sau strtol.
Parametri
| Parametru | Descriere |
|---|---|
format |
Șablonul: %d (int), %ld, %f (float), %lf (double), %c, %19s (cuvânt de cel mult 19 caractere), %[^\n] (până la sfârșitul rândului). |
... |
Adresele variabilelor în care se scriu valorile (&x), în ordinea specificatorilor. |
Ce returnează
Numărul de câmpuri citite și salvate (poate fi mai mic decât cel cerut), sau EOF dacă intrarea s-a terminat sau a apărut o eroare înainte de prima conversie.
Exemple
Exemplul 1: Un nume, o vârstă și o medie
%19s citește un cuvânt de cel mult 19 caractere în nume (fără &, pentru că este tablou). %lf este obligatoriu pentru double. Valoarea 3 confirmă că toate câmpurile au fost citite.
#include <stdio.h>
int main(void) {
char nume[20];
int varsta;
double medie;
printf("Nume, vârstă, medie: ");
int citite = scanf("%19s %d %lf", nume, &varsta, &medie);
printf("\nCâmpuri citite: %d\n", citite);
if (citite == 3) {
printf("%s are %d de ani și media %.2f.\n", nume, varsta, medie);
}
return 0;
}
Ce scrie utilizatorul (intrare)
Ana 21 9.35
Rezultat
Nume, vârstă, medie:
Câmpuri citite: 3
Ana are 21 de ani și media 9.35.
Exemplul 2: Verificarea valorii returnate la date greșite
Utilizatorul a scris doi în loc de un număr. scanf nu poate converti textul, returnează 0 și lasă variabila neschimbată. Fără verificare, programul ar fi lucrat cu o valoare greșită.
#include <stdio.h>
int main(void) {
int bucati = 0;
printf("Câte bucăți? ");
if (scanf("%d", &bucati) != 1) {
printf("\nTrebuie să scrii un număr întreg.\n");
return 0;
}
printf("\nAi comandat %d bucăți.\n", bucati);
return 0;
}
Ce scrie utilizatorul (intrare)
doi
Rezultat
Câte bucăți?
Trebuie să scrii un număr întreg.
Exemplul 3: Citirea până la sfârșitul intrării
Bucla citește note cât timp scanf găsește un număr. La sfârșitul intrării returnează EOF, iar bucla se oprește. Rândurile noi dintre numere nu contează, pentru că %d sare peste spații albe.
#include <stdio.h>
int main(void) {
int nota, numar = 0, suma = 0;
while (scanf("%d", ¬a) == 1) {
suma += nota;
numar++;
}
if (numar > 0) {
printf("Am citit %d note, media este %.2f\n", numar, (double)suma / numar);
}
return 0;
}
Ce scrie utilizatorul (intrare)
9 10
7
8 10
Rezultat
Am citit 5 note, media este 8.80
Greșeli frecvente
- Uiți
&:scanf("%d", varsta).scanfprimește valoarea în loc de adresă și scrie la o adresă oarecare (comportament nedefinit, de obicei programul se oprește). - Folosești
%sfără lățime. Un cuvânt mai lung decât tabloul depășește memoria rezervată. Scrie%19spentru un tablou de 20. - Citești un număr, apoi un caracter cu
%c, și primești'\n'rămas de la Enter. Pune un spațiu în fața lui:" %c", ca să sară peste spațiile albe. - Folosești
%fpentru o variabilădouble. Lascanf,doublecere%lf;%feste pentrufloat.
Comenzi înrudite
fgets: Citește un rând întreg (cu tot cu spații) într-un tablou de caractere, fără să depășească dimensiunea dată.getchar: Citește un singur caracter de la intrarea standard; returnează EOF când intrarea s-a terminat.strtol și strtod: Transformă text în număr și îți spune unde s-a oprit citirea și dacă valoarea a depășit limitele.printf: Afișează text formatat pe ecran: un șablon cu specificatori (%d, %s, %.2f) completați cu valorile primite după el.fscanf: Citește valori dintr-un fișier după un șablon, ca scanf; returnează câte câmpuri a citit sau EOF la final.Pointeri (& și *): O variabilă care păstrează adresa altei variabile; cu * citești sau modifici valoarea de la acea adresă.