Riepilogo
Questa lezione apre la settima unità del corso, dedicata al testo e ai file. Spiega a che cosa serve l’unità: insegnare a trattare il testo come dato, con la sua codifica reale, e a far sì che un programma legga e scriva file senza rompersi davanti a un input malformato; presenta le sue quattro lezioni e il filo che le unisce; ricorda ciò che l’unità dà per scontato, soprattutto che un carattere è, per la macchina, un numero, e i vettori, i record e le funzioni delle unità 5 e 6; formula il problema che l’unità risolve, quello di un programma dall’aspetto corretto che perde dati senza avvisare, si ferma alla prima riga inattesa e misura male i nomi con gli accenti; anticipa che una lettera non sempre occupa un byte; e mostra dove conduce, nell’unità 8 e nel corso Programmazione in C++ II.
Obiettivi di apprendimento
- Descrivere la sequenza dei contenuti dell’unità e spiegare che cosa ogni lezione apporta alla successiva.
- Ricordare la rappresentazione dei caratteri come codici numerici (lezione 2.4) e scrivere un codice in binario e in esadecimale.
- Anticipare, con un esempio, che una lettera non sempre è un byte, e che perciò contare byte non è contare lettere.
- Riconoscere che cosa ci si aspetta di saper fare alla fine dell’unità, e distinguerlo da ciò che si imparerà nell’unità successiva e in Programmazione in C++ II.
Valutazione d’ingresso
Prima di percorrere l’unità conviene misurare il punto di partenza. Questa valutazione è un’autovalutazione: non ha voto, e il suo unico scopo è orientare lo studio. Le prime sei domande verificano ciò che l’unità dà per scontato: il codice di un carattere, la scrittura di un numero in binario e in esadecimale, una maschera di bit, il percorso di un vettore che ne filtra gli elementi, ciò che accade quando una lettura riceve lettere invece di un numero e la definizione di un record. Le quattro successive toccano, nell’ordine delle lezioni, le idee centrali dell’unità: ciò che restituisce una ricerca che non trova nulla, la dimensione di una parola con un accento, la riga vuota che compare quando si mescolano due modi di leggere e il file che non si è potuto aprire. Nessuno è tenuto a indovinare già queste quattro, e in alcune di esse «non lo so ancora» è una risposta onesta: ogni risposta, giusta o no, spiega il punto e nomina la lezione che lo tratta. Le stesse abilità si misurano di nuovo alla fine, nella lezione di sintesi.
Prima di iniziare l’unità, misura il tuo punto di partenza. È un’autovalutazione breve: non riceve voto e il risultato resta solo nel tuo browser.
Domanda 1Dalle unità precedentiChe cosa scrive
std::println("{:d} {:d}", 'A', 'a');?Crede che le minuscole seguano immediatamente le maiuscole; tra le due ci sono 32 codici, con alcuni segni in mezzo.Ignora che{:d}chiede il codice; senza di esso,std::printlnscriverebbe la lettera.Inverte l’ordine: in ASCII le maiuscole hanno codici minori delle minuscole.Uncharconserva un numero, il codice del carattere, e{:d}chiede di scrivere quel numero e non la lettera. In ASCII le maiuscole cominciano da 65 e le minuscole da 97: la distanza è 32, un solo bit. La lezione Il testo non è ASCII parte da qui per spiegare che cosa accade alle lettere che non sono in ASCII.Ripassare: Caratteri, booleani, conversioni e costanti
Domanda 2Dalle unità precedentiCome si scrive 233 in binario e in esadecimale?
Raggruppa male i quattro bit bassi:1001vale 9, non 1.Legge i bit al contrario, dal meno significativo al più significativo.Confonde la scrittura esadecimale con quella decimale.. Raggruppati a quattro a quattro da destra, i bit1110e1001valgono 14 e 9, cioèee9. È il codice della «é», e l’unità mostrerà che in un file di testo attuale quel codice non si conserva come un solo bytee9, ma come due.Ripassare: Gli interi e la loro rappresentazione
Domanda 3Dalle unità precedentiQuanto vale
0xB1 & 0xC0?Confonde&con|: l’OR bit a bit accende i bit alti invece di selezionarli.Crede che la maschera non cambi nulla; azzera i sei bit bassi.Confonde&con^, lo XOR.0xB1è10110001e0xC0è11000000: l’AND bit a bit conserva solo i due bit alti di0xB1, che sono10. Questa maschera è quella che la lezione Il testo non è ASCII usa per riconoscere i byte che continuano una lettera.Ripassare: Bit e libreria matematica
Domanda 4Dalle unità precedentiChe cosa scrive
std::vector<int> v{4, 7, 10, 3}; std::vector<int> w{}; for (const int x : v) { if (x % 2 == 0) { w.push_back(x); } } std::println("{}", w);?Inverte la condizione:x % 2 == 0è vera per i pari.Crede chepush_backcopi il vettore intero, o che il filtro si applichi ave si scrivav.Crede chepush_backaggiunga all’inizio; aggiunge alla fine.Il ciclo percorreve copia inwsolo i pari, nell’ordine in cui compaiono;vnon cambia. L’unità usa lo stesso schema con il testo: percorrere i byte di una stringa e tenerne alcuni, o percorrere le righe di un file e tenere quelle valide.Ripassare: Vettori
Domanda 5Dalle unità precedentiDopo
int n{-1}; std::cin >> n;, l’utente digitaabc. Quanto valene che cosa accade alle letture successive?Crede che la lettura fallita non lasci traccia; la lascia nella variabile e nello stato dello stream.Suppone che C++ avvisi dell’input non valido; il programma continua come se la lettura fosse andata bene.Confonde la lettura di un intero con quella di un carattere.La lettura salta gli spazi, trova una lettera che non può cominciare un numero e fallisce: lo standard stabilisce che la variabile riceve 0, che la lettera resta nello stream e che lo stream resta in errore, senza alcun messaggio. La lezione Leggere bene insegna a distinguere questo fallimento dalla fine dei dati e a ripristinarsi.Ripassare: Input, output ed errori
Domanda 6Dalle unità precedentiQuale delle definizioni seguenti dichiara correttamente un record con un titolo e un anno?
Dimentica il punto e virgola dopo la graffa di chiusura, il primo errore di chi scrive record; il compilatore lo segnala con precisione.Separa i campi con virgole, come gli elementi di un elenco; ogni campo è una dichiarazione e termina con un punto e virgola.Confonde un record, con campi di tipi diversi e dotati di nome, con un vettore, i cui elementi sono tutti dello stesso tipo.Ogni campo si dichiara come una variabile, con il suo tipo, il suo nome e il suo valore iniziale tra graffe, e la definizione termina con un punto e virgola dopo la graffa di chiusura. La lezione File di testo riempie vettori di record come questo con le righe di un file.Ripassare: Record
Domanda 7Se
sèstd::string s{"casa azul"};, che cosa restituisces.find("x")?È la convenzione di altri linguaggi;std::size_tnon ha segno, e un-1convertito in esso è proprionpos, ma confrontare il risultato con-1funziona solo grazie a questa conversione e produce un avviso del compilatore.Confonde «non trovato» con la posizione 0, che è quella di un’occorrenza all’inizio della stringa.È una risposta onesta: la lezione 7.1 presentafindenpos.Domanda 8Che cosa scrive
std::println("{}", std::string{"año"}.size());in un programma salvato in UTF-8, come quelli di questo corso?Conta lettere;sizeconta i byte in cui sono scritte.Crede che ogni lettera occupi due byte; quelle di ASCII ne occupano uno.È una risposta onesta: la lezione 7.2 lo spiega byte per byte.sizeconta byte, non lettere: nella parola spagnola «año» (anno), la «a» e la «o» ne occupano uno ciascuna, e la «ñ», che non è in ASCII, ne occupa due in UTF-8. La lezione Il testo non è ASCII spiega perché e insegna a contare le lettere.Ripassare: Il testo non è ASCII
Domanda 9Un programma esegue
int age{}; std::string name{}; std::cin >> age; std::getline(std::cin, name);e l’utente digita36, preme Invio, digitaAnae preme Invio. Che cosa resta inname?Suppone chegetlinecominci dalla riga seguente; comincia dove>>si è fermato.Crede chegetlinerilegga ciò che>>ha già consumato.È una risposta onesta: la lezione 7.3 comincia da questo difetto.>>legge il 36 e lascia nello stream l’a capo che lo seguiva;std::getlinelegge fino al primo a capo, che è quello, e restituisce ciò che c’era prima: niente. La lezione Leggere bene lo spiega e lo evita constd::ws.Ripassare: Leggere bene
Domanda 10Un programma esegue
std::ifstream in{"data.txt"}; int x{-1}; in >> x;, madata.txtnon esiste nella cartella da cui viene eseguito. Che cosa accade?Suppone che aprire un file inesistente sia un errore che C++ segnala; il programma continua senza avvisare.Confonde l’apertura in lettura con l’apertura in scrittura, che sì crea il file.È una risposta onesta: la lezione 7.4 comincia da questo controllo.L’apertura di un file può fallire, e il fallimento si vede solo interrogando lo stream: per questo si scriveif (!in)prima di leggere. La lezione File di testo fa di questo controllo una regola e spiega da quale cartella dipende la ricerca.Ripassare: File di testo
Caricamento del contenuto…