Partie 14: Entrée/Sortie — Programmation orientée objet en C++

1,812 views
1,690 views

Published on

Support material for a continued education course "Introduction to object oriented programming in C++".
In French.

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,812
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
98
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Partie 14: Entrée/Sortie — Programmation orientée objet en C++

  1. 1. Programmation Orientée Objet en C++ 14ème Partie: Entrée/Sortie Fabio Hernandez Fabio.Hernandez@in2p3.fr
  2. 2. Vue dEnsemble Notions de base Types, variables, opérateurs Contrôle dexécution Fonctions Mémoire dynamique Qualité du logiciel Evolution du modèle objet Objets et classes Fonctions membres Classes génériques Héritage Polymorphisme Héritage multiple Entrée/sortiePOO en C++: Entrée/Sortie 479 © 1997-2003 Fabio HERNANDEZ
  3. 3. Table des Matières Introduction Flot de sortie Flot dentrée Fichiers et flots Etat dun flot Formatage Manipulateurs RésuméPOO en C++: Entrée/Sortie 480 © 1997-2003 Fabio HERNANDEZ
  4. 4. Introduction Les mécanismes dentrée/sortie ne font pas partie du langage C++ proprement dit Ils ont été implémentés en C++ et font partie de la bibliothèque standard livrée avec tout compilateur Au niveau le plus bas, un fichier est vu comme comme une séquence (stream) doctets Des composants de la bibliothèque standard soccupent du transfert de ces octets pas de notion de type Au plus haut niveau, un fichier est vu comme une séquence de données de type différent (caractères, valeurs arithmétiques, objets,...)POO en C++: Entrée/Sortie 481 © 1997-2003 Fabio HERNANDEZ
  5. 5. Introduction (suite) La bibliothèque standard fournit un ensemble dopérations pour lentrée/sortie des objets des types de base du langage (char, int, float, long,...) Le programmeur peut étendre quelques unes de ces opérations pour lentrée/sortie des objets des classes définies par lui Un flux (stream) est une abstraction logicielle représentant un flot de données entre une source (producteur de données) une cible (consommateur des données) Opérateur de sortie ou dinjection dans le flot: << une valeur/donnée est dite injectée dans le flot de sortie Opérateur dentrée ou dextraction du flot: >> une valeur/donnée est dite extraite du flot dentréePOO en C++: Entrée/Sortie 482 © 1997-2003 Fabio HERNANDEZ
  6. 6. Introduction (suite) La direction de lopérateur indique le sens du flux de données transfert de données du flot vers la variable counter cin >> counter; transfert de données de la variable counter vers le flot cout << counter; Par défaut, un programme en C++ peut utiliser trois flots prédéfinis cout: flot de sortie correspondant à la sortie standard (instance de la classe ostream_withassign) cin: flot dentrée correspondant à lentrée standard (instance de la classe istream_withassign) cerr: flot de sortie correspondant à la sortie standard derreur (instance de la classe ostream_withassign)POO en C++: Entrée/Sortie 483 © 1997-2003 Fabio HERNANDEZ
  7. 7. Introduction (suite) Pour utiliser ces flots il est nécessaire dinclure le fichier iostreamPOO en C++: Entrée/Sortie 484 © 1997-2003 Fabio HERNANDEZ
  8. 8. Hiérarchie de classes ios ostream istream ostream_withassign iostream istream_withassign iostream_withassignPOO en C++: Entrée/Sortie 485 © 1997-2003 Fabio HERNANDEZ
  9. 9. Hiérarchie de classes - standard ios_base basic_ios<> ios / wios basic_stream<> basic_ostream<> istream / wistream ostream / wostream basic_iostream<> iostream / wiostreamPOO en C++: Entrée/Sortie 486 © 1997-2003 Fabio HERNANDEZ
  10. 10. Contrôle dAvancement Introduction Flot de sortie Flot dentrée Fichiers et flots Etat dun flot Formatage Manipulateurs RésuméPOO en C++: Entrée/Sortie 487 © 1997-2003 Fabio HERNANDEZ
  11. 11. Flot de sortie La méthode générale est dappliquer lopérateur de sortie au flot cout #include <iostream> void main() { cout << "The result of 13+89 is " << 13+89 << endl; } A lécran sera affiché The result of 13+89 is 102 Le flot cout accepte des arguments de tous les types primitifs du langage, y compris les pointeurs (char*, int*, ...) qui sont affichés comme des valeurs hexadécimalesPOO en C++: Entrée/Sortie 488 © 1997-2003 Fabio HERNANDEZ
  12. 12. Flot de sortie (suite) Affichage de pointeurs int counter = 1024; int* counterPtr = &counter; cout << "counter = " << counter << " &counter = " << &counter << endl; cout << "*counterPtr = " << *counterPtr << " counterPtr = " << counterPtr << endl; affichera à lécran counter = 1024 &counter = 0x7ffff0b4 *counterPtr = 1024 counterPtr = 0x7ffff0b4POO en C++: Entrée/Sortie 489 © 1997-2003 Fabio HERNANDEZ
  13. 13. Flot de sortie (suite) Affichage de pointeurs à des chaînes de caractères char* author = "Carl Sagan"; cout << "author = " << author << endl; affichera à lécran author = Carl Sagan Les objets de type char* ne sont pas interprétés comme des pointeurs mais comme des chaînes de caractères Une conversion forcée est nécessaire pour afficher ladresse mémoire du pointeur cout << "author = " << (void*)author << endl;POO en C++: Entrée/Sortie 490 © 1997-2003 Fabio HERNANDEZ
  14. 14. Flot de sortie (suite) Les opérateurs de sortie sont de la forme class ostream: public ios { ... ostream& operator<<(int value); ... }; chaque opérateur retourne une référence à lobjet ostream sur lequel il a été appelé, afin de pouvoir le cascader dans une seule instruction cout << 1234 << "hello"; La valeur de ce qui est équivalent à retour de cout.operator<<(1234).operator<<("hello"); lopération est une référence à un objet de la classe ostreamPOO en C++: Entrée/Sortie 491 © 1997-2003 Fabio HERNANDEZ
  15. 15. Flot de sortie (suite) En plus de lopérateur dinjection <<, la classe ostream contient dautres méthodes, parmi lesquelles ostream& put(char aChar) pour insérer un caractère dans le flot Exemple: cout.put(A); ostream& write(const char* buffer, int howmany) pour insérer howmany caractères à partir de buffer dans le flot Exemple: cout.write("This is a string", 3); ostream& flush() pour vider les tampons du flux et forcer lenvoi immédiat des données sur le fichier/écranPOO en C++: Entrée/Sortie 492 © 1997-2003 Fabio HERNANDEZ
  16. 16. Contrôle dAvancement Introduction Flot de sortie Flot dentrée Fichiers et flots Etat dun flot Formatage Manipulateurs RésuméPOO en C++: Entrée/Sortie 493 © 1997-2003 Fabio HERNANDEZ
  17. 17. Flot dentrée Lopérateur dentrée >> fonctionne de façon similaire à lopérateur de sortie Tous les opérateurs dextraction pour les types primitifs sont fournis, y compris pour char* int min; int max; cout << "Please enter min and max: " << endl; cin >> min >> max; cout << "Values just read are: " << min << " and " << max << endl;POO en C++: Entrée/Sortie 494 © 1997-2003 Fabio HERNANDEZ
  18. 18. Flot dentrée (suite) Lopérateur dentrée peut être utilisé comme la condition dune boucle char nextChar; while (cin >> nextChar) { // process nextChar here } extraction dun caractère à la fois de lentrée standard quand la fin de lentrée est atteinte, la condition est fausse et la boucle finitPOO en C++: Entrée/Sortie 495 © 1997-2003 Fabio HERNANDEZ
  19. 19. Flot dentrée (suite) La séquence de caractères ab c d e est traitée comme une suite de cinq caractères (a,b,c,d,e): les espaces et les changements de ligne servent uniquement pour séparer les différents valeurs et ne sont pas traités comme caractères Extraction dune chaîne de caractères char string[20]; cin >> string; une chaîne est traitée comme une suite de caractères délimitée par des espacesPOO en C++: Entrée/Sortie 496 © 1997-2003 Fabio HERNANDEZ
  20. 20. Flot dentrée (suite) Extraction dune chaîne de caractères (suite) linstruction cin >> string; avec lentrée Gone with the wind produit comme résultat la chaîne Gone dans la variable string Le caractère nulle (0) est rajouté en fin de chaîne pendant lentrée la taille de la variable doit être au moins la longueur de la chaîne plus unPOO en C++: Entrée/Sortie 497 © 1997-2003 Fabio HERNANDEZ
  21. 21. Flot dentrée (suite) Exemple: déterminer la longueur maximum dune suite de chaînes de caractères extraites de lentrée standard char buffer[100]; int maxLength = -1; int currentLength = 0; while (cin >> buffer) { currentLength = strlen(buffer); if (maxLength < currentLength) maxLength = currentLength; } cout << "The max length is " << maxLength << endl;POO en C++: Entrée/Sortie 498 © 1997-2003 Fabio HERNANDEZ
  22. 22. Flot dentrée (suite) Le manipulateur setw peut être utilisé pour éviter le dépassement de la capacité du buffer dentrée const int MaxCapacity = 100; char buffer[MaxCapacity]; while (cin >> setw(MaxCapacity) >> buffer) { ... } setw divise une chaîne dune longueur égale ou supérieure à MaxCapacity en deux ou plusieurs chaînes dune longueur maximum de MaxCapacity-1 le fichier den-tête iomanip.h doit être inclus pour pouvoir utiliser setwPOO en C++: Entrée/Sortie 499 © 1997-2003 Fabio HERNANDEZ
  23. 23. Flot dentrée (suite) En plus de lopérateur dextraction >>, la classe istream contient dautres méthodes, parmi lesquelles int get() pour extraire le caractère suivant dans le flot dentrée int nextChar = cin.get(); while (nextChar != EOF) { cout.put(nextChar); nextChar = cin.get(); } istream& get(char& aChar) extrait le caractère suivant dans le flux (même si cest un espace) et le place dans aChar istream& get(char* buffer, int count, char delim=n) extrait count-1 caractères du flux et les place dans buffer. La lecture sarrête au délimiteur delim ou à la fin du fichier. Le délimiteur nest pas extrait du fluxPOO en C++: Entrée/Sortie 500 © 1997-2003 Fabio HERNANDEZ
  24. 24. Flot dentrée (suite) Autres méthodes de istream (suite) istream& getline(char* buffer, int count, char delim=n) comme la méthode précédente sauf que le délimiteur est extrait du flux mais pas recopié dans buffer istream& read(char* buffer, int count) pour extraire un bloc dau plus count octets et les placer dans buffer. Le nombre doctets effectivement lus peut être obtenu par la méthode gcount() int gcount() retourne le nombre doctets extraits lors de la dernière lecturePOO en C++: Entrée/Sortie 501 © 1997-2003 Fabio HERNANDEZ
  25. 25. Contrôle dAvancement Introduction Flot de sortie Flot dentrée Fichiers et flots Etat dun flot Formatage Manipulateurs RésuméPOO en C++: Entrée/Sortie 502 © 1997-2003 Fabio HERNANDEZ
  26. 26. Fichiers et flots ios ostream fstreambase istream ofstream ifstream iostream fstreamPOO en C++: Entrée/Sortie 503 © 1997-2003 Fabio HERNANDEZ
  27. 27. Fichiers et flots - standard ios_base basic_ios<> ios / wios basic_istream<> basic_ostream<> istream / wistream ostream / wostream basic_iostream<> iostream / wiostream basic_ifstream<> basic_fstream<> basic_ofstream<> ifstream / wifstream fstream / wfstream ofstream / wofstreamPOO en C++: Entrée/Sortie 504 © 1997-2003 Fabio HERNANDEZ
  28. 28. Fichiers et flots (suite) Il est possible de créer un objet flot associé à un fichier sur disque Plusieurs classes prédéfinies dans le fichier fstream.h ifstream permet dattacher un fichier à un flot dentrée ofstream permet dattacher un fichier à un flot de sortie fstream permet dattacher un fichier à un flot dentrée et de sortie Pour associer un flot à un fichier de sortie on utilise le constructeur ou la méthode open ofstream outFile("MyFile.dat", ios::out); outFile << "Ceci nest pas une chaine" << endl; les arguments spécifiés sont le nom du fichier et le mode douverture, qui peut être ios::out ou ios::app un fichier existant ouvert en mode ios::out perdra toutes ses donnéesPOO en C++: Entrée/Sortie 505 © 1997-2003 Fabio HERNANDEZ
  29. 29. Fichiers et flots (suite) Exemple: lecture des caractères de lentrée standard et écriture dans un fichier #include <fstream> // Open the file ofstream outFile("copy.dat", ios::out); // Copy all the characters from input to the file char nextChar = cin.get(); while (nextChar != EOF) { outFile.put(nextChar); nextChar = cin.get(); }POO en C++: Entrée/Sortie 506 © 1997-2003 Fabio HERNANDEZ
  30. 30. Fichiers et flots (suite) Sur un flot on peut envoyer des objets dune classe définie par nous, pourvu que lopérateur << soit défini pour la classe ofstream outFile("Points.dat", ios::out); Point aPoint(14.0, 34.0); outFile << aPoint; Pour lire un fichier on utilise la classe ifstream #include <fstream> ifstream inputFile("copy.dat", ios::in); char nextChar; while (inputFile.get(nextChar)) cout.put(nextChar);POO en C++: Entrée/Sortie 507 © 1997-2003 Fabio HERNANDEZ
  31. 31. Fichiers et flots (suite) Exemple: lire les chaînes des caractères dun fichier dentrée et les envoyer vers un fichier de sortie séparées dun retour de chariot const char* inputFileName = "Input.dat"; const char* outputFileName = "Output.dat"; ifstream inputFile(inputFileName, ios::in); ofstream outputFile(outputFileName, ios::out); const int MaxCapacity = 1024; char buffer[MaxCapacity]; while (inputFile >> setw(MaxCapacity) >> buffer) outputFile << buffer << endl;POO en C++: Entrée/Sortie 508 © 1997-2003 Fabio HERNANDEZ
  32. 32. Fichiers et flots (suite) Louverture du fichier (dentrée et de sortie) peut être faite après la construction du flot ifstream inputFile; // Do something here inputFile.open("Input.dat", ios::in); Le flot peut être déconnecté du fichier avec la méthode close() et connecté à un autre fichier ultérieurement inputFile.close(); // ... inputFile.open("AnotherInputFile.dat", ios::in); Le comportement est similaire pour les objets de la classe ofstreamPOO en C++: Entrée/Sortie 509 © 1997-2003 Fabio HERNANDEZ
  33. 33. Fichiers et flots (suite) Un flot de la classe fstream peut être attaché à un fichier pour la lecture ou pour lécriture de données fstream file; file.open("MyFile.dat", ios::out); file << 1234; file.close(); file.open("MyFile.dat", ios::in); int i; file >> i; file.close(); cout << "i = " << i << endl;POO en C++: Entrée/Sortie 510 © 1997-2003 Fabio HERNANDEZ
  34. 34. Fichiers et flots (suite) Attachement dun flot à un fichier en entrée et en sortie simultanément fstream file("MyFile.dat", ios::in|ios::out); istream offre des méthodes pour se positionner dans le fichier istream& seekg(streampos position); istream& seekg(streamoff offset, ios::seek_dir direction); streampos et streamoff sont des synonymes de long ios::seek_dir est une énumération qui définit trois valeurs ios::beg, ios::cur et ios::end ios::beg pour se positionner offset octets à partir du début du fichierPOO en C++: Entrée/Sortie 511 © 1997-2003 Fabio HERNANDEZ
  35. 35. Fichiers et flots (suite) Positionnement dans le fichier (suite) ios::end pour se positionner offset octets à partir de la fin du fichier ios::cur pour se positionner offset octets à partir de la position actuelle du fichier Avec la méthode tellg() on obtient la position actuelle dans le fichier streampos mark = outputFile.tellg(); // .... if (cancelOutput) outputFile.seekg(mark); // ...POO en C++: Entrée/Sortie 512 © 1997-2003 Fabio HERNANDEZ
  36. 36. Contrôle dAvancement Introduction Flot de sortie Flot dentrée Fichiers et flots Etat dun flot Formatage Manipulateurs RésuméPOO en C++: Entrée/Sortie 513 © 1997-2003 Fabio HERNANDEZ
  37. 37. Etat dun flot La classe ios décrit les caractéristiques communes des flots dentrée et de sortie Cest une classe de base de toute la hiérarchie des flots Elle fournit des méthodes pour interroger létat dun flot formater linformation à envoyer dans un flot Parmi les méthodes publiques de cette classe on peut citer int good() retourne une valeur différente de zéro si la dernière opération dentrée/sortie sest effectuée avec succès et zéro dans le cas contraire int fail() fait linverse de good() int eof() retourne une valeur différente de zéro si la fin du fichier a été atteinte et zéro dans le cas contrairePOO en C++: Entrée/Sortie 514 © 1997-2003 Fabio HERNANDEZ
  38. 38. Etat dun flot (suite) On peut utiliser ce mécanisme de contrôle de létat pour déterminer si louverture dun fichier sest effectuée correctement ifstream inputFile("MyFile.dat", ios::in); // Is the file really open? if (inputFile.fail()) { // or: if (!inputFile.good()) cout << "Error opening file" << end; return false; } // File is open, so continue...POO en C++: Entrée/Sortie 515 © 1997-2003 Fabio HERNANDEZ
  39. 39. Contrôle dAvancement Introduction Flot de sortie Flot dentrée Fichiers et flots Etat dun flot Formatage Manipulateurs RésuméPOO en C++: Entrée/Sortie 516 © 1997-2003 Fabio HERNANDEZ
  40. 40. Formatage Chaque objet flot conserve en permanence un ensemble dindicateurs pour contrôler les opérations de formatage de linformation Ces indicateurs sont contenus dans la classe ios dont toutes les classes de la bibliothèque standard dentrée/sortie héritent Cette classe fournit des méthodes permettant dinterroger et de modifier les caractéristiques du formatage précision des valeurs en virgule flottante justification de la sortie à droite ou à gauche modification de la base de représentation pour les valeur numériques (hexadécimal, octal, décimal, ...) notation scientifique pour les valeurs en virgule flottantePOO en C++: Entrée/Sortie 517 © 1997-2003 Fabio HERNANDEZ
  41. 41. Formatage (suite) Par défaut les entiers sont lus et écrits en notation décimale Pour changer la base on utilise des manipulateurs (hex, dec, oct) int i = 512; cout << "Default i = " << i << endl; cout << "Octal i = " << oct << i << endl; cout << "Hexadecimal i = " << hex << i << endl; cout << "Decimal i = " << dec << i << endl; affiche Default i = 512 Utilisation des Octal i = 1000 manipulateurs Hexadecimal i = 200 de changement Decimal i = 512 de basePOO en C++: Entrée/Sortie 518 © 1997-2003 Fabio HERNANDEZ
  42. 42. Formatage (suite) Par défaut, une valeur en virgule flottante est affichée avec 5 chiffres décimaux Ce nombre peut être obtenu à laide de la fonction membre int ios::precision() const et modifié avec la fonction membre int ios::precision(int newPrecision) cout << "Precision: " << cout.precision() << "sqrt(2.0): " << sqrt(2.0) << endl; cout.precision(12); cout << "Precision: " << cout.precision() << "sqrt(2.0): " << sqrt(2.0) << endl; cout.precision(3); cout << "Precision: " << cout.precision() << "sqrt(2.0): " << sqrt(2.0) << endl;POO en C++: Entrée/Sortie 519 © 1997-2003 Fabio HERNANDEZ
  43. 43. Formatage (suite) Affichage Precision: 6 sqrt(2.0): 1.41421 Precision: 12 sqrt(2.0): 1.41421356237 Precision: 3 sqrt(2.0): 1.41 Dune façon générale, létat de formatage de chaque flot fait partie de ces attributs (classe ios) Cet état est maintenu dans une variable de type long et modifié via des méthodes de la classe ios et des masques de bits Exemple: contrôler laffichage de la virgule pour les valeurs en virgule flottantePOO en C++: Entrée/Sortie 520 © 1997-2003 Fabio HERNANDEZ
  44. 44. Formatage (suite) Exemple (suite) cout << 10.70 << endl; affichera 10.7 et cout << 10.0 << endl; affichera 10 Pour afficher les zéros après la virgule cout.setf(ios::showpoint);POO en C++: Entrée/Sortie 521 © 1997-2003 Fabio HERNANDEZ
  45. 45. Formatage (suite) Plusieurs notations pour les valeurs en virgule flottante fixe (1.4142) scientifique (1.41424e+000) // show in default mode cout << sqrt(2.0) << endl; // set to fixed mode cout.setf(ios::fixed, ios::floatfield); cout << sqrt(2.0) << endl; // set to scientific mode cout.setf(ios::scientific, ios::floatfield); cout << sqrt(2.0) << endl;POO en C++: Entrée/Sortie 522 © 1997-2003 Fabio HERNANDEZ
  46. 46. Formatage (suite) Pour les valeurs entières on peut afficher lindicateur de la base décimal octal hexadécimal cout.setf(ios::showbase); cout << 15 << endl; cout << hex << 15 << endl; cout << oct << 15 << endl; affichera 15 0xf 017POO en C++: Entrée/Sortie 523 © 1997-2003 Fabio HERNANDEZ
  47. 47. Formatage (suite) La largeur du champ de sortie peut être modifiée ainsi que le caractère de remplissage pour la justification cout.width(5); cout.fill(*); cout << 123 << endl; affiche **123 et si lon modifie la justification cout.setf(ios::left); cout << 123 << endl; affiche 123**POO en C++: Entrée/Sortie 524 © 1997-2003 Fabio HERNANDEZ
  48. 48. Contrôle dAvancement Introduction Flot de sortie Flot dentrée Fichiers et flots Etat dun flot Formatage Manipulateurs RésuméPOO en C++: Entrée/Sortie 525 © 1997-2003 Fabio HERNANDEZ
  49. 49. Manipulateurs Ce sont des fonctions associées au flots dentrée/sortie qui permettent de modifier létat du flot dans la même instruction dentrée/sortie // Display in hexadecimal mode Manipulateurs cout << hex << 512 << endl; sans arguments // Change the width and padding character cout << setw(5) << setfill(*) << endl; Manipulateurs avec des argumentsPOO en C++: Entrée/Sortie 526 © 1997-2003 Fabio HERNANDEZ
  50. 50. Manipulateurs (suite) Un certain nombre de manipulateurs sont prédéfinis dec, hex et oct pour les changements de base endl, ends et flush ws pour sauter les espaces setbase(int newBase) pour modifier la base setfill(int fillChar) pour modifier le caractère de remplissage setprecision(int newPrecision) pour modifier la précision setw(int width) pour modifier la largeur ... On peut aussi définir ses propres manipulateurs (voir documentation)POO en C++: Entrée/Sortie 527 © 1997-2003 Fabio HERNANDEZ
  51. 51. Contrôle dAvancement Introduction Flot de sortie Flot dentrée Fichiers et flots Etat dun flot Formatage Manipulateurs RésuméPOO en C++: Entrée/Sortie 528 © 1997-2003 Fabio HERNANDEZ
  52. 52. Résumé C++ offre en standard une bibliothèque de classes pour lentrée/sortie de données Une abstraction logicielle est introduite pour représenter un flot de données entre une source productrice dinformation et une cible consommatrice On utilise les même mécanismes pour injecter ou extraire des données des flots standards et des fichiers disque Des fonctions de formatage de linformation sont fournies et peuvent être étenduesPOO en C++: Entrée/Sortie 529 © 1997-2003 Fabio HERNANDEZ

×