{ M1103—Cours de C++ (3) A. Casali / M. Laporte • Exam de vendredi (quand, quoi

{ M1103—Cours de C++ (3) A. Casali / M. Laporte • Exam de vendredi (quand, quoi) • Evaluation des enseignements • Projet A. Flux de sortie B. Flux d’entrée C. Gestion des erreurs de lecture D. Positionnement dans un flux E. Etat d’un flux F. Classe stringstream Plan A. Flux de sortie On souhaite écrire le résultat de l’application dans un fichier de sortie Solution 1 : rediriger la sortie standard vers un fichier a.out > OutFile Problèmes : • Comment fait-on si on souhaite écrire dans un fichier depuis une interface graphique (ie, on n’a pas accès à la console); • Comment peut on écrire dans plusieurs fichiers en même temps (on ne peut faire que 2 redirections : la sortie standard et le flux d’erreur). Solution 2 : utiliser les flux de sortie A.1 Declaration #include <fstream> using namespace std; ofstream ofs; Output File STREAM A.2 Ouverture ofs.open (string FileName [, Mode XXX]); On lie le flux de sortie ofs au fichier FileName selon le mode spécifier. La chaine FileName est le chemin relatif au fichier souhaité. Le « point de départ » du chemin relatif est l’exécutable. Par défaut (aucun mode n’est spécifié) : • Le fichier texte est accessible en écriture; • Si le fichier n’existe pas, il est créé; • S’il existe, les informations sont ajoutées avant celles qui existaient déjà. Exemple : ofs.open ("test.txt"); A.3 Déclaration et Ouverture En même temps qu’on déclare un flux sur un fichier, il est possible de spécifier: • le fichier en question; • Son mode d’ouverture. ofstream ofs (string Filename [,Mode XXX]); Exemple : ofstream ofs ("test.txt"); A.4 Les modes d’ouverture Tous les modes sont des constantes de la classe ios_base. On accède à un mode en utilisant la notation ios_base::ModeName ModeName Signification Accès out output (sortie) Accès au flux en écriture in input (entrée) Accès au flux en lecture binary binary (binaire) Effectue les opérations d’E/S en mode binaire et non en mode texte ate at end (à la fin) Position la tête (de lecture) à la fin du fichier app append (ajout) Les ajouts se font à la fin du fichier et non au début trunc truncate (troncature) Supprime le contenu du fichier Exemple : ofstream ofs ("test.txt", ios_base::out|ios_base::binary); Le caractère ‘|’ permet d’enchainer les options. A.5 Fermeture d’un flux de sortie On appelle la méthode close () sur le flux de sortie. Exemple : ofs.close (); Un flux de sortie ne peut avoir, en même temps, les modes trunc et app! A.6 Ecriture dans un flux de sortie On utilise l’injecteur (<<) pour pouvoir écrire dans un flux de sortie, de la même manière qu’on l’utilise pour pouvoir écrire dans la console (qui est un cas particulier des flux de sortie). L’injecteur fonctionne : • Pour tous les types (int, char, bool, …); • Pour certaines classes (string). Exemple : ofs << 10 << endl; ofs << true << endl; ofs << ‘a’ << endl; ofs << "coucou" << endl; more test.txt 10 1 a coucou De la même façon qu’on ne peut afficher un vecteur (vector) sur la console, on ne peut pas l’injecter directement dans un flux de sortie. Exemple : CVInt V (10); ofs << V; XXX.cxx:YYY:Z: error: cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&' ofs << V; ^ In file included from /opt/local/include/gcc48/c++/iostream:39:0, from hello.cpp:9: /opt/local/include/gcc48/c++/ostream:602:5: error: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = std::vector<int>]' operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x) ^ La seule et unique solution consiste à injecter chaque élément du vecteur les uns à la suite des autres en utilisant une boucle. Exemple : for (int x : V) ofs << setw (3) << x; more test.txt 0 0 0 0 0 0 0 0 0 0 A. Flux de sortie B. Flux d’entrée C. Gestion des erreurs de lecture D. Positionnement dans un flux E. Etat d’un flux F. Classe stringstream Plan B. Flux d’entrée On souhaite lire des données pour une application depuis un fichier d’entrée Solution 1 : rediriger l’entrée standard depuis un fichier a.out < InFile Problèmes : • Comment fait-on si on souhaite lire des données depuis le Net (voir S3); • Comment peut on lire depuis plusieurs fichiers en même temps (on ne peut faire qu’une redirections : l’entrée standard). Solution 2 : utiliser les flux d’entrée B.1 Declaration #include <fstream> using namespace std; ifstream ifs; Input File STREAM B.2 Ouverture ifs.open (string FileName [, Mode XXX]); On lie le flux d’entrée ifs au fichier FileName selon le mode spécifier. La chaine FileName est le chemin relatif au fichier souhaité. Le « point de départ » du chemin relatif est l’exécutable. Par défaut (aucun mode n’est spécifié) : • Le fichier texte est accessible en lecture; • Si le fichier n’existe pas, il n’est pas créé (aucun contrôle quant à la validité du fichier est effectué); • S’il existe, la tête de lecture est positionnée au début du fichier. Exemple : ifs.open ("test.txt"); B.3 Déclaration et Ouverture En même temps qu’on déclare un flux sur un fichier, il est possible de spécifier: • le fichier en question; • Son mode d’ouverture. ifstream ifs (string Filename [,Mode XXX]); Exemple : ifstream ifs ("test.txt"); B.4 Les modes d’ouverture Les différents mode d’ouverture sont les mêmes que pour les flux de sortie. On ne peut toujours pas associer les mode trunc et ate. De même l’ouverture échoue si le mode est trunc, mais pas out. B.5 Fermeture d’un flux d’entrée On appelle la méthode close () sur le flux d’entrée. Exemple : ifs.close (); B.6 Existence d’un flux d’entrée On appelle la méthode is_open () sur le flux d’entrée. Cette méthode renvoie vrai si le flux existe, faux sinon. Exemple : if (!ifs.is_open ()) { cerr << "File not found" << endl; return; } //le fichier existe et est accessible B.7 Lecture depuis un flux d’entrée On utilise l’extracteur (>>) pour pouvoir lire depuis un flux d’entrée, de la même manière qu’on l’utilise pour pouvoir lire depuis le clavier (qui est un cas particulier des flux d’entrée). L’extracteur fonctionne : • Pour tous les types (int, char, bool, …); • Pour certaines classes (string). Exemple (1): string str; ifs >> str; cout << str << endl; int x; ifs >> x; cout << x << endl; bool b; ifs >> b; cout << b << endl; char c; ifs >> c; cout << c << endl; test.txt : coucou 10 1 a coucou 10 1 a Exemple (2) : test.txt : 0 0 0 0 0 0 0 0 0 0 int x; ifs >> x; cout << x << endl; bool b; ifs >> b; cout << b << endl; char c; ifs >> c; cout << c << endl; string str; ifs >> str; cout << str << endl; 0 0 0 0 Données non exploitées Tête de lecture B.7 Lecture du contenu d’un fichier On aimerait avoir un algorithme du type : tant_que (NON fin_de_fichier) faire UnType Resultat <- lire_quelque_chose; Manipuler (Resultat); ffaire PB : on ne peut détecter la fin d’un fichier qu’après avoir fait une tentative de lecture. Solution : boucle UnType Resultat <- lire_quelque_chose; si (fin_de_fichier) sortie; Manipuler (Resultat); fboucle Pour détecter la fin d’un fichier, on appelle la méthode eof () sur le flux d’entrée. Cette méthode renvoie vrai si la fin d’un fichier a été atteint, faux sinon. Exemple : while (true) { AType VarIdent = ReadSomething (); if (ifs.eof ()) break; Manipulate (VarIdent); } Problème (1) : Lire un vecteur d’entier préalablement stocké CVInt V; while (true) { int x; ifs >> x; if (ifs.eof ()) break; V.push_back (x); } Problème (2) : Connaître le nombre de mots d’un fichier texte Commande wc –w sous Linux unsigned wc (0); string str; while (true) { ifs >> str; if (ifs.eof ()) break; ++wc; } cout << setw (8) << wc << ' ' << __FILE__ << endl; Macro du C permettant de connaitre le nom du fichier courant. Problème (3) : Connaitre le nombre de caractères d’un fichier texte Commande wc –c sous Linux Solution 1 : unsigned wc (0); char c; while (true) { ifs >> c; if (ifs.eof ()) break; ++wc; } cout << setw (8) << wc << ' ' << __FILE__ << endl; Pb : quid de l’encodage des caractères  wc -c hello.cxx wc: hello.cxx: Illegal byte sequence 8230 hello.cxx ./a.out 6414 hello.cxx Solution 2 : utiliser la méthode get (char &) de la classe ifstream. unsigned wc = 0; char c; while (true) { ifs.get (c); if (ifs.eof ()) break; ++wc; } cout << setw (8) << wc << ' ' << __FILE__ << endl; Problème (4) : Connaitre le nombre de lignes d’un fichier texte Commande wc –l sous Linux Lorsqu’on souhaite lire une ligne complète depuis la console : ~void getline (cin, string &); Or on souhaite lire depuis un flux d’entrée. Donc : ~void getline (ifstream &, string &); Le flux est passé par référence car il uploads/Litterature/ m1103-amphi03.pdf

  • 24
  • 0
  • 0
Afficher les détails des licences
Licence et utilisation
Gratuit pour un usage personnel Attribution requise
Partager