Résumé
Cette leçon ouvre la septième unité du cours, consacrée au texte et aux fichiers. Elle explique à quoi sert l’unité : apprendre à traiter le texte comme une donnée, avec son encodage réel, et à faire qu’un programme lise et écrive des fichiers sans se briser devant une entrée mal formée ; elle présente ses quatre leçons et le fil qui les unit ; elle rappelle ce que l’unité tient pour acquis, surtout qu’un caractère est, pour la machine, un nombre, ainsi que les vecteurs, les enregistrements et les fonctions des unités 5 et 6 ; elle formule le problème que l’unité résout, celui d’un programme d’apparence correcte qui perd des données sans prévenir, s’arrête à la première ligne inattendue et mesure mal les noms à accents ; elle annonce qu’une lettre n’occupe pas toujours un octet ; et elle montre où elle mène, dans l’unité 8 et dans le cours Programmation en C++ II.
Objectifs d’apprentissage
- Décrire la séquence des contenus de l’unité et expliquer ce que chaque leçon apporte à la suivante.
- Rappeler la représentation des caractères par des codes numériques (leçon 2.4) et écrire un code en binaire et en hexadécimal.
- Anticiper, sur un exemple, qu’une lettre n’est pas toujours un octet, et que, pour cette raison, compter des octets n’est pas compter des lettres.
- Reconnaître ce que l’on attend de savoir faire à la fin de l’unité, et le distinguer de ce qui s’apprendra dans l’unité suivante et dans Programmation en C++ II.
Évaluation d’entrée
Avant de parcourir l’unité, il convient de mesurer le point de départ. Cette évaluation est une autoévaluation : elle n’est pas notée, et son seul but est d’orienter l’étude. Les six premières questions vérifient ce que l’unité tient pour acquis : le code d’un caractère, l’écriture d’un nombre en binaire et en hexadécimal, un masque de bits, le parcours d’un vecteur qui filtre ses éléments, ce qui se passe quand une lecture reçoit des lettres au lieu d’un nombre et la définition d’un enregistrement. Les quatre suivantes touchent, dans l’ordre des leçons, aux idées centrales de l’unité : ce que renvoie une recherche qui ne trouve rien, la taille d’un mot accentué, la ligne vide qui apparaît quand on mélange deux manières de lire et le fichier qui n’a pas pu être ouvert. Personne n’est tenu de réussir ces quatre-là dès maintenant, et pour certaines d’entre elles « je ne le sais pas encore » est une réponse honnête : chaque réponse, juste ou non, explique le point et nomme la leçon qui le traite. Les mêmes compétences sont mesurées de nouveau à la fin, dans la leçon de synthèse.
Avant de commencer l’unité, mesurez votre point de départ. C’est une autoévaluation brève : elle n’est pas notée et son résultat n’est conservé que dans votre navigateur.
Question 1Des unités précédentesQu’écrit
std::println("{:d} {:d}", 'A', 'a');?Elle croit que les minuscules suivent immédiatement les majuscules ; entre les deux il y a 32 codes, avec quelques signes au milieu.Elle ignore que{:d}demande le code ; sans lui,std::printlnécrirait la lettre.Elle inverse l’ordre : en ASCII, les majuscules ont des codes plus petits que les minuscules.Uncharcontient un nombre, le code du caractère, et{:d}demande d’écrire ce nombre et non la lettre. En ASCII, les majuscules commencent à 65 et les minuscules à 97 : l’écart est de 32, un seul bit. La leçon Le texte n’est pas ASCII part de là pour expliquer ce qui arrive aux lettres qui ne sont pas dans ASCII.Question 2Des unités précédentesComment s’écrit 233 en binaire et en hexadécimal ?
Elle groupe mal les quatre bits de poids faible :1001vaut 9, et non 1.Elle lit les bits à l’envers, du moins significatif au plus significatif.Elle confond l’écriture hexadécimale avec l’écriture décimale.. Groupés quatre par quatre à partir de la droite, les bits1110et1001valent 14 et 9, c’est-à-direeet9. C’est le code du « é », et l’unité montrera que, dans un fichier texte actuel, ce code n’est pas enregistré comme un seul octete9, mais comme deux.À revoir : Les entiers et leur représentation
Question 3Des unités précédentesQue vaut
0xB1 & 0xC0?Elle confond&avec|: le OU bit à bit allume les bits de poids fort au lieu de les sélectionner.Elle croit que le masque ne change rien ; il efface les six bits de poids faible.Elle confond&avec^, le OU exclusif.0xB1est10110001et0xC0est11000000: le ET bit à bit ne conserve que les deux bits de poids fort de0xB1, qui sont10. Ce masque est celui que la leçon Le texte n’est pas ASCII utilise pour reconnaître les octets qui continuent une lettre.À revoir : Bits et bibliothèque mathématique
Question 4Des unités précédentesQu’écrit
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);?Elle inverse la condition :x % 2 == 0est vraie pour les nombres pairs.Elle croit quepush_backcopie le vecteur entier, ou que le filtre s’applique àvet que c’estvqui s’écrit.Elle croit quepush_backajoute au début ; il ajoute à la fin.La boucle parcourtvet ne copie danswque les nombres pairs, dans l’ordre où ils apparaissent ;vne change pas. L’unité utilise le même schéma avec du texte : parcourir les octets d’une chaîne et en garder certains, ou parcourir les lignes d’un fichier et garder les lignes valides.À revoir : Vecteurs
Question 5Des unités précédentesAprès
int n{-1}; std::cin >> n;, l’utilisateur tapeabc. Que vautn, et qu’arrive-t-il aux lectures suivantes ?Elle croit que la lecture échouée ne laisse pas de trace ; elle en laisse une dans la variable et dans l’état du flux.Elle suppose que C++ signale l’entrée non valide ; le programme continue comme si la lecture s’était bien passée.Elle confond la lecture d’un entier avec celle d’un caractère.La lecture saute les espaces, trouve une lettre qui ne peut pas commencer un nombre et échoue : la norme fixe que la variable reçoit 0, que la lettre reste dans le flux et que le flux passe en erreur, sans aucun message. La leçon Bien lire apprend à distinguer cet échec de la fin des données et à s’en rétablir.À revoir : Entrée, sortie et erreurs
Question 6Des unités précédentesLaquelle des définitions suivantes déclare correctement un enregistrement avec un titre et une année ?
Elle oublie le point-virgule après l’accolade fermante, la première erreur de qui écrit des enregistrements ; le compilateur la signale avec précision.Elle sépare les champs par des virgules, comme les éléments d’une liste ; chaque champ est une déclaration et se termine par un point-virgule.Elle confond un enregistrement, aux champs nommés et de types différents, avec un vecteur, dont les éléments sont tous du même type.Chaque champ se déclare comme une variable, avec son type, son nom et sa valeur initiale entre accolades, et la définition se termine par un point-virgule après l’accolade fermante. La leçon Fichiers texte remplit des vecteurs d’enregistrements comme celui-ci avec les lignes d’un fichier.À revoir : Enregistrements
Question 7Si
seststd::string s{"casa azul"};, que renvoies.find("x")?C’est la convention d’autres langages ;std::size_tn’a pas de signe, et un-1converti en ce type est justementnpos, mais comparer le résultat à-1ne fonctionne que grâce à cette conversion et produit un avertissement du compilateur.Elle confond « non trouvé » avec la position 0, qui est celle d’une occurrence au début de la chaîne.C’est une réponse honnête : la leçon 7.1 présentefindetnpos.findrenvoie une position, de typestd::size_t, et, quand il ne trouve rien, il renvoie une valeur qu’aucune position ne peut avoir :npos, qui vaut, sur 64 bits, . La leçon Chaînes de caractères apprend à toujours la comparer de manière explicite.À revoir : Chaînes de caractères
Question 8Qu’écrit
std::println("{}", std::string{"año"}.size());dans un programme enregistré en UTF-8, comme ceux de ce cours ?Elle compte des lettres ;sizecompte les octets dans lesquels elles sont écrites.Elle croit que toute lettre occupe deux octets ; celles d’ASCII en occupent un.C’est une réponse honnête : la leçon 7.2 l’explique octet par octet.sizecompte des octets, non des lettres : dans le mot espagnol « año » (année), le « a » et le « o » en occupent un chacun, et la « ñ », qui n’est pas dans ASCII, en occupe deux en UTF-8. La leçon Le texte n’est pas ASCII explique pourquoi et apprend à compter les lettres.À revoir : Le texte n’est pas ASCII
Question 9Un programme exécute
int age{}; std::string name{}; std::cin >> age; std::getline(std::cin, name);et l’utilisateur tape36, appuie sur Entrée, tapeAnaet appuie sur Entrée. Que reste-t-il dansname?Elle suppose quegetlinecommence à la ligne suivante ; il commence là où>>s’est arrêté.Elle croit quegetlinerelit ce que>>a déjà consommé.C’est une réponse honnête : la leçon 7.3 commence par ce défaut.Question 10Un programme exécute
std::ifstream in{"data.txt"}; int x{-1}; in >> x;, maisdata.txtn’existe pas dans le dossier depuis lequel il est lancé. Que se passe-t-il ?Elle suppose qu’ouvrir un fichier inexistant est une erreur que C++ signale ; le programme continue sans avertir.Elle confond l’ouverture en lecture avec l’ouverture en écriture, qui, elle, crée le fichier.C’est une réponse honnête : la leçon 7.4 commence par cette vérification.L’ouverture d’un fichier peut échouer, et l’échec ne se voit qu’en interrogeant le flux : c’est pourquoi on écritif (!in)avant de lire. La leçon Fichiers texte fait de cette vérification une règle et explique de quel dossier dépend la recherche.À revoir : Fichiers texte
Chargement du contenu…