Riepilogo
L’input è la frontiera attraverso cui il mondo entra in un programma, e il mondo non rispetta le specifiche. Questa lezione insegna a leggere senza fidarsi: a leggere righe intere con std::getline e a evitare la riga vuota che compare quando lo si mescola con >>; a consultare lo stato di uno stream e a distinguere con esso tre situazioni che la lezione Input, output ed errori ha visto solo confuse (il dato non valido, il numero che non ci sta e la fine dei dati); a ripristinarsi da una lettura fallita con clear e ignore; e, come forma più sicura, a leggere ogni dato come testo e convertirlo con std::from_chars, accettandolo solo se la conversione ha consumato il testo intero. Termina con una funzione readInt, con il suo contratto, che il resto del corso può riutilizzare.
Obiettivi di apprendimento
- Leggere righe intere con
std::getline, spiegare perché ungetlineche segue una lettura con>>restituisce una riga vuota, ed evitarlo constd::ws. - Consultare lo stato di uno stream dopo una lettura con
fail()edeof(), e distinguere con esso un dato non valido, un numero che non sta nel suo tipo e la fine dell’input. - Scrivere un ciclo di lettura che si ripristini da un input non valido con
cleareignore, e che termini se l’input finisce. - Validare un numero letto come testo con
std::from_chars, esigendo che non ci sia errore e che si consumi la stringa intera, e incapsulare la validazione in funzioni con contratto.
La frontiera, ancora una volta
La lezione Input, output ed errori ha stabilito tre fatti su std::cin >> n: la lettura si ferma, senza consumarlo, al primo carattere che non può continuare il numero; se non riesce a leggerne nessuno, lo stream resta in stato di errore e ogni lettura successiva non fa nulla; e if (std::cin) permette di sapere se qualcosa è fallito. La lezione Cicli ha aggiunto che la condizione while (std::cin >> value) termina sia se l’input finisce sia se arriva un dato non valido. Ora, con questi strumenti un programma rileva che qualcosa è andato storto, ma non sa che cosa né può fare altro che arrendersi.
Questa lezione parte da un principio di progettazione, quello della programmazione difensiva alla frontiera: ogni dato che entra viene validato prima di essere usato, e il programma che lo valida distingue il dato non valido, che ammette una correzione (richiederlo, saltarlo, segnalarlo), dalla fine dei dati, che non l’ammette. Se è così, servono tre cose: leggere il dato così come è stato scritto, cioè una riga; sapere perché una lettura è fallita; e restituire allo stream la capacità di leggere.
Caricamento del contenuto…