La Funzione scanf() e l'Input da Tastiera in C
Argomenti: stdio.h, scan formatted, operatore di indirizzo (&), specificatori %d, %lf, %c, %s, gestione del buffer
Se printf() serve a comunicare verso l'esterno, la funzione scanf() è lo strumento principale del linguaggio C per **ricevere dati dall'utente** tramite la tastiera. Il suo nome sta per "scan formatted" (scansione formattata) e fa parte della libreria standard <stdio.h>.
1. Sintassi e l'Operatore di Indirizzo (&)
Regola Fondamentale: Comunicare a scanf() dove salvare il valore in RAM
Per salvare il valore digitato dall'utente all'interno di una variabile, scanf() necessita dell'indirizzo di memoria di quella variabile. Per questo motivo, il nome della variabile deve essere quasi sempre preceduto dall'operatore & (ampersand).
Sintassi di base:
scanf("%Specificatore", &nome_variabile);
int eta;
scanf("%d", &eta);
L'operatore & indica a scanf l'indirizzo esatto della scatola in RAM.
int eta;
scanf("%d", eta); // ERRORE GRAVE!
Senza &, il programma proverà a scrivere in una posizione di memoria casuale e andrà in crash (Segmentation Fault).
2. Specificatori di Formato per l'Input
Attenzione a Double: Differenze tra specificatori di printf() e scanf()
| Specificatore | Tipo di Dato | Esempio di Utilizzo | Note e Regole |
|---|---|---|---|
%d |
int / short |
scanf("%d", &numero); |
Legge un numero intero decimali. Ignora gli spazi vuoti iniziali. |
%lf |
double |
scanf("%lf", &prezzo); |
OBBLIGATORIO %lf: Usare `%f` per leggere un `double` in scanf() causa un errore di lettura! |
%f |
float |
scanf("%f", &peso); |
Si usa esclusivamente per le variabili di tipo float. |
%c |
char |
scanf(" %c", &scelta); |
Legge un singolo carattere. Nota: Legge anche spazi vuoti e invii (\n). |
%s |
Stringa (char[]) |
scanf("%s", nome); |
NO &: Per le stringhe/array non si mette la ampersand &. Si ferma al primo spazio vuoto. |
3. Esempio Pratico Completo
Laboratorio C: Inserimento dati da tastiera e stampa di conferma
| 1 | #include <stdio.h> |
| 2 | |
| 3 | int main(void) { |
| 4 | int eta; |
| 5 | double mediaVoti; |
| 6 | |
| 7 | // 1. Richiesta numero intero |
| 8 | printf("Inserisci la tua eta': "); |
| 9 | scanf("%d", &eta); |
| 10 | |
| 11 | // 2. Richiesta numero decimale (double -> %lf) |
| 12 | printf("Inserisci la tua media scolastica: "); |
| 13 | scanf("%lf", &mediaVoti); |
| 14 | |
| 15 | // 3. Stampa dei dati letti |
| 16 | printf("\nDati registrati: %d anni, media %.2f\n", eta, mediaVoti); |
| 17 | |
| 18 | return 0; |
| 19 | } |
- Sempre anticipare con printf:
scanf()non mostra alcun messaggio a schermo, attende solo l'input. È buona norma farla precedere sempre da unprintf()che spieghi cosa digitare. - Il tasto INVIO: L'input viene trasmesso a
scanf()soltanto dopo che l'utente ha premuto il tasto INVIO sulla tastiera. - Specificatore double: Nota come alla riga 13 per
doublesi usi%lfinscanf(), mentre alla riga 16 per la stampa inprintf()basti%.2f.
4. Il Problema del Buffer e dei Caratteri (%c)
Inconveniente Classico: Come evitare che il tasto INVIO salti la lettura di un carattere
Quando l'utente digita un numero e preme INVIO, il tasto INVIO genera un carattere invisibile di andata a capo (\n) che rimane intrappolato nel buffer di input. Se subito dopo provi a leggere un carattere con scanf("%c", &carattere), scanf leggerà il tasto INVIO rimasto nel buffer anziché attendere il nuovo tasto!
La Soluzione: Aggiungere uno Spazio
Per ignorare automaticamente i residui di INVIO o spazi nel buffer, basta inserire **uno spazio vuoto prima del `%c`** nella stringa di formato:
scanf(" %c", &scelta); // Notare lo spazio prima di %c
Il Valore di Ritorno di scanf()
Ancora come printf(), anche scanf() restituisce un valore intero: indica il numero di elementi letti con successo. Se ad esempio chiedi 1 numero intero e l'utente digita delle lettere, scanf() restituirà 0, permettendoti di intercettare l'errore di input!
Riepilogo per lo studio
• Metti sempre l'operatore & davanti alle variabili in scanf() (es tranne per le stringhe).
• Ricorda di usare %lf per le variabili di tipo double.
• Aggiungi uno spazio prima di %c (ossia " %c") quando devi leggere un singolo carattere dopo aver letto dei numeri.
In sintesi
Argomenti: concetti principali, riepilogo, competenze
- La funzione scanf() appartiene a <stdio.h> ed è lo strumento standard per leggere dati inseriti dall'utente da tastiera.
- Per salvare i dati nelle variabili è obbligatorio usare l'operatore di indirizzo & (es. &numero), tranne che per le stringhe.
- Per i numeri decimali di tipo double è fondamentale usare lo specificatore %lf e non %f.
- scanf() lascia i caratteri di invio (\n) nel buffer di input, problema da gestire prima di leggere singoli caratteri %c.
- Passare l'indirizzo di memoria della variabile a scanf() tramite l'operatore &.
- Associare lo specificatore di formato corretto in base al tipo di dato (%d, %f, %lf, %c, %s).
- Leggere più variabili all'interno di una singola istruzione scanf().
- Gestire il newline residuo nel buffer durante la lettura dei caratteri con %c.