Vai al contenuto
Topos Uranos

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

  1. Leggere righe intere con std::getline, spiegare perché un getline che segue una lettura con >> restituisce una riga vuota, ed evitarlo con std::ws.
  2. Consultare lo stato di uno stream dopo una lettura con fail() ed eof(), e distinguere con esso un dato non valido, un numero che non sta nel suo tipo e la fine dell’input.
  3. Scrivere un ciclo di lettura che si ripristini da un input non valido con clear e ignore, e che termini se l’input finisce.
  4. 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.