scanf în C

Citește valori de la tastatură după un șablon (%d, %lf, %s) și le scrie la adresele primite; returnează câte valori a citit.

Sintaxă
#include <stdio.h>
int scanf(const char *format, ...);

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", &nota) == 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). scanf primește valoarea în loc de adresă și scrie la o adresă oarecare (comportament nedefinit, de obicei programul se oprește).
  • Folosești %s fără lățime. Un cuvânt mai lung decât tabloul depășește memoria rezervată. Scrie %19s pentru 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 %f pentru o variabilă double. La scanf, double cere %lf; %f este pentru float.

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ă.