La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Chapitre IX Gestion de flux.

Présentations similaires


Présentation au sujet: "Chapitre IX Gestion de flux."— Transcription de la présentation:

1 Chapitre IX Gestion de flux

2 Généralités sur les flux
Un flux ou canal de données représente un ensemble de données pouvant être manipulé à la fois en lecture et en écriture. Offre une transparence vis-à-vis de la source ou de la destination des données c’est-à-dire un programme peut utiliser les mêmes instructions de manipulation de flux pour tous les types de flux de sortie (écran, fichier, mémoire) pour tous les types de flux d’entrée (clavier, fichier, mémoire). Un programme peut utiliser les mêmes instructions pour afficher des données à l’écran ou pour écrire ces données dans un fichier sur le disque dur. Ex.: En C++, tous les flux sont symbolisés par des classes qui font partie de la librairie iostream (input-output stream, pour flux d’entrées/sorties). Chapitre IX - Gestion de flux

3 Généralités sur les flux
Ces classes correspondent aux différents types de flux et sont présentées sous la forme d’une arborescence: classe de base qui regroupe les caractéristiques communes aux flux ios classe de base du flux d’entrée istream ostream classe de base du flux de sortie flux d’entrée sur fichier ifstream iostream ofstream flux de sortie sur fichier canaux standards Chapitre IX - Gestion de flux

4 Généralités sur les flux
Toutes les classes de la librairie iostream disposent de 2 opérateurs surchargés: << écrire vers un flux de sortie >> lire à partir d’un flux d’entrée. L’opérande de gauche de l’opérateur << doit correspondre à un objet de la classe ostream (ou dérivée). L’opérande de gauche de l’opérateur >> doit correspondre à un objet de la classe istream (ou dérivée). Ces 2 opérateurs ont été définis pour les types de données suivants: char, short, int, long, float, double, long double, char * et void *. comme par exemple, ostream & operator << (ostream & out, char valeur); On peut donc lire et écrire des variables de ces différents types de données à l’aide de ces 2 opérateurs. Chapitre IX - Gestion de flux

5 Généralités sur les flux
C++ fournit 4 flux prédéfinis: cout: correspond au flux de sortie standard (écran par défaut) (dérivée de la classe ostream) cin: désigne le flux d’entrée standard (clavier par défaut) (dérivée de la classe istream) cerr: désigne la sortie erreur standard (écran par défaut) clog: permet à la fois d’envoyer des messages d’erreurs vers la sortie erreur standard (écran par défaut) et de remplir un fichier de log (fichier d’alerte) Pour pouvoir utiliser la librairie iostream, il est nécessaire d’inclure le fichier "iostream.h"   ou encore <iostream>. La gestion des flux se caractérise par une lecture/écriture séquentielle des données. Chapitre IX - Gestion de flux

6 Affichage à l’écran avec cout
int entier = 12; …… cout << "  Entier : "  << entier << '\n'; Ex.: saut de ligne La librairie iostream fournit un certain nombre de mots clés qui permettent de modifier les caractéristiques d’un flux. cout << manipulateur; Syntaxe: Le padding consiste à compléter, généralement avec des espaces ou des zéros, un élément affiché à l’écran. Chapitre IX - Gestion de flux

7 Affichage à l’écran avec cout
Manipulateur Objectif Note : Pour employer un manipulateur de flux paramétré, vous devez inclure : #include <iomanip>. Ex.: endl n’est pas un manipulateur de flux paramétré.

8 Affichage à l’écran avec cout
Les méthodes de la classe ios Méthode Objectif Chapitre IX - Gestion de flux

9 Affichage à l’écran avec cout
Utilisation de la fonction setf() pour modifier l’alignement des colonnes affichées i.e. choisir d’aligner à gauche ou à droite les éléments affichés. Ex.: cout.setf(ios::right, ios::adjustfield); cout << setw(12) << "AAA" << endl; cout << setw(12) <<   "BBBBBB" << endl; alignement à droite AAA BBBBBB sous réserve que la taille d’affichage soit spécifiée Alignement à gauche: cout.setf(ios::left, ios::adjustfield); Chapitre IX - Gestion de flux

10 Affichage à l’écran avec cout
Ex.: int Entier = 15; …….. cout << "Conversions" << endl; cout << "Entier : " << Entier << endl; cout << "Hexa : " << hex << Entier << endl; cout << "Oct : " << oct << Entier << endl; cout << dec; Conversions Entier : 15 Hexa : f Oct : 17 On repasse en base décimale. Chapitre IX - Gestion de flux

11 Affichage à l’écran avec cout
Ex.: float Decimal = 10.25; …….. cout.setf(ios::right, ios::adjustfield); cout <<   "Decimal : "   << setw(8) << Decimal << endl; cout <<   "Decimal : "   << setw(8) << (Decimal + 100) << endl; cout <<   "Decimal : "   << setw(8) << (Decimal+1000) << endl; cout <<   "Decimal : "   << setw(8) << setfill('0') << Decimal << endl; Decimal : Decimal : Decimal : Decimal : Chapitre IX - Gestion de flux

12 Affichage à l’écran avec cout
Ex.: float PI = ; …….. cout << "PI : " << PI << endl; cout << "PI : " << setprecision(3) << PI << endl; cout << "PI : " << setprecision(4) << PI << endl; cout << "PI : " << setprecision(5) << PI << endl; PI : PI : 3.14 PI : 3.142 PI : Chapitre IX - Gestion de flux

13 Affichage à l’écran avec cout
Ex.: char chaine[20+1]; strcpy(chaine, "Ceci est un essai."); …….. cout << "Chaine : " << chaine << endl; cout << "Chaine : " ; cout.width(25); cout.fill('-'); cout.setf(ios::left, ios::adjustfield); cout << chaine << endl; Chaine : Ceci est un essai. Chaine : Ceci est un essai Chapitre IX - Gestion de flux

14 Saisir au clavier avec cin
L’objet cin est employé pour saisir des informations au clavier. défini à partir d’une classe dérivée de istream. utilise l’opérateur surchargé >> pour saisir au clavier les valeurs ° des variables de type primaire (char, int, float, etc.) ° des chaînes de caractères. Ex.: int i; char c; float f1, f2; ….. cout << "Saisissez un nombre: " ; cin >> i; cout << "Saisissez un caractere: " ; cin >> c; ….. cout << "Saisissez 2 nombres reels: " ; cout << "Un espace entre les 2 nombres reels: "; cin >> f1 >> f2; Chapitre IX - Gestion de flux

15 Saisir au clavier avec cin
Puisque l’espace sert à séparer les valeurs d’une saisie multiple, on ne peut saisir de chaîne avec des espaces en utilisant l’opérateur >>. Il n’y a pas de contrôle au niveau du nombre de caractères saisis au clavier: l’opérateur >> n’est pas capable nativement de déterminer que le nombre de caractères saisis au clavier dépasse la taille de la chaîne à initialiser. Il n’y a pas de contrôle de type au moment de la saisie. Il est donc possible de saisir des caractères dans une variable entière. La variable sera considérée invalide uniquement à l’issue de la saisie. Chapitre IX - Gestion de flux

16 Saisie de chaînes au clavier et nombre de caractères
Danger char chaine[5+1]; …... cout << "Saisissez une chaine de caracteres: " ; cin >> chaine; Écrasez l’espace après le tableau chaine. Solution: préciser à l’objet cin le # de caractères à prendre en compte. char chaine[5+1]; …... cout << "Saisissez une chaine de caracteres: " ; cin.width(sizeof(chaine)); cin >> chaine; Les 5 premiers caractères seront utilisés plus '\0 ’ même si l’on saisit au clavier davantage. Chapitre IX - Gestion de flux

17 Saisie de chaînes au clavier incluant des espaces
La classe istream contient la fonction membre getline() qui permet de saisir des chaînes de caractères. Contrairement à l’opérateur >>, cette fonction autorise la saisie d’espaces à l’intérieur d’une chaîne. Prototype de la méthode getline() istream& getline(char * chaine, int nombre, char fin = '\n'); référence à la classe istream # max. de caractères à saisir + '\n' chaîne à saisir caractère qui représentera la fin de la saisie Chapitre IX - Gestion de flux

18 Saisie de chaînes au clavier incluant des espaces
#include <iostream.h> #include <string.h> class personne { protected: char Nom[20+1]; …… public: void Saisir(); …... }; void personne::Saisir() { cout << "Nom : " ; cin.getline(Nom, sizeof(Nom)); ……. } …… Ex.: Chapitre IX - Gestion de flux

19 Redéfinition des opérateurs de flux
Les 2 opérateurs << et >> ont été surchargés pour les types primaires du langage et les chaînes de caractères. On peut donc manipuler des variables correspondant à ces types de données. On peut aussi redéfinir les 2 opérateurs du langage pour nos propres classes. Ainsi, nos classes pourront utiliser le mécanisme d’entrées/sorties prévu par la librairie iostream exactement comme les types primaires ou les chaînes de caractères. Chapitre IX - Gestion de flux

20 Redéfinition des opérateurs de flux
TRAME << et >> pourront accéder à tous les membres de MaClasse. class MaClasse { public: …… friend ostream& operator << (ostream& out, MaClasse& v); friend ostream& operator << (ostream& out, MaClasse * v); friend istream& operator >> (istream& in, MaClasse& v); friend istream& operator >> (istream& in, MaClasse * v); }; ostream& operator << (ostream& out, MaClasse& v) ……. return out; } << et >> peuvent être utilisés avec l’adresse ou la référence d’un objet de type MaClasse. Chapitre IX - Gestion de flux

21 Redéfinition des opérateurs de flux
L’appel par valeur n’est pas permis. TRAME ostream& operator << (ostream& out, MaClasse * v) { ……. return out; } istream& operator >> (istream& in, MaClasse& v) return in; …….. pointeur à un objet de type MaClasse référence à un objet de type ostream Dès que << sera utilisé avec comme opérande de gauche un objet de type ostream et comme opérande de droite un objet de la classe MaClasse, cette fonction sera exécutée. Renvoi de la référence à l’objet ostream récupéré en paramètre. Permet des E / S en cascade.

22 Redéfinition des opérateurs de flux
Ex. tiré de Stéphane Dupin, Le langage C++, 1999, pp #include <iostream.h> #include <string.h> class Voiture { protected: char Marque[20+1]; char Modele[20+1]; char Prix[20+1]; public: Voiture(char *ma = "", char * mo = "", char * pr = ""); friend ostream& operator << (ostream& out, Voiture& v); friend istream& operator >> (istream& in, Voiture& v); }; Chapitre IX - Gestion de flux

23 Redéfinition des opérateurs de flux
Voiture::Voiture(char *ma, char *mo, char *pr) { strcpy(Marque, ma); strcpy(Modele, mo); strcpy(Prix, pr); } ostream& operator << (ostream& out, Voiture& v) out.setf(ios::left, ios::adjustfield); out << " Marque : "; out << v.Marque; out << " Modele : "; out << v.Modele; out << " Prix : "; out << v.Prix; out << endl; return out; Chapitre IX - Gestion de flux

24 Redéfinition des opérateurs de flux
istream& operator >> (istream& in, Voiture& v) { cout << " Marque : "; in.getline(v.Marque, sizeof(v.Marque)); cout << " Modele : "; in.getline(v.Modele, sizeof(v.Modele)); cout << " Prix : "; in.getline(v.Prix, sizeof(v.Prix)); return in; } void main() Voiture v("Lotus",  "Seven",  "300000 "); cout << " Voiture : " << v << endl; cout << " Saisissez la marque le modele et le prix : " << endl; cin >> v; cout << endl <<   "Resultat : " << v; Chapitre IX - Gestion de flux

25 Redéfinition des opérateurs de flux
Voiture : Marque : Lotus Modele : Seven Prix : Saisissez la marque le modele et le prix : Marque : Aston Martin Modele : DB7 Prix : Resultat : Marque : Aston Martin Modele : DB7 Prix : Chapitre IX - Gestion de flux

26 Redéfinition des opérateurs de flux
Dans le cas où nous avons à réaliser une opération dans le cas d’un pointeur vers la classe, on procède ainsi: ostream& operator << (ostream& out, Voiture * v) { out.setf(ios::left, ios::adjustfield); out << " Marque : "; out << v -> Marque; out << " Modele : "; out << v -> Modele; out << " Prix : "; out << v -> Prix; out << endl; return out; } Chapitre IX - Gestion de flux

27 Redéfinition des opérateurs de flux
La possibilité de surcharger ces opérateurs facilite l’extension du langage à de nouveaux types de données. Exemple I : ostream & operator << (ostream & out, const Fraction & valeur) { out << valeur.numerateur() << "/" << valeur.denominateur(); return out; } . . . Fraction n(3, 4); cout << "La valeur de n est : " << n << "\n"; Chapitre IX - Gestion de flux

28 Redéfinition des opérateurs de flux
Exemple II : istream & operator >> (istream & in, temps & T) { int heures; int minutes; int secondes; in >> heures >> minutes >> secondes; T = temps(heures, minutes, secondes); return in; } Ce paramètre référence doit être non const, puisqu’il est modifié à l’entrée. Chapitre IX - Gestion de flux

29 Lire et écrire à partir ou vers un fichier
Toutes les opérations de gestion de flux étudiées peuvent s’appliquer à la gestion de fichiers. Il suffit de créer un objet de type ofstream pour écrire dans un fichier un objet de type ifstream pour lire un fichier. Ces 2 classes sont déclarées dans le fichier d’en-tête fstream.h et elles dérivent respectivement des classes ostream et istream. Modes d’organisation des enregistrements dans un fichier. Fichiers à accès séquentiel où les enregistrements sont stockés dans un ordre imposé par un champ de clé de l’enregistrement. On peut supposer que l’utilisateur introduise les enregistrements dans l’ordre du champ de clé ou prévoir un tri automatique. Fichiers à accès aléatoire Chapitre IX - Gestion de flux

30 Création d’un fichier à accès séquentiel
#include <iostream.h> #include <fstream.h> int main() { ofstream Fichier_de_sortie("E:\\ESSAI.TXT", ios::out); if (!Fichier_de_sortie) cout << "Impossible d ’ouvrir le fichier."; return 1; } Accès en écriture au fichier E:\\ ESSAI.TXT Mode d’ouverture par défaut du fichier pour écrire des données. Détermine si l ’ouverture du fichier a réussi Les fichiers existants ouverts avec le mode ios sont tronqués, i.e. toutes les données sont éliminées. Chapitre IX - Gestion de flux Si le fichier n’existe pas encore, il est créé.

31 Création d’un fichier à accès séquentiel
cout << "Entrez matricule, nom et montant : "; int matricule; char nom[20]; float montant; while (cin >> matricule >> nom >> montant) Fichier_de_sortie << matricule << ' ' << nom << ' ' << montant << "\n"; return 0; } Fin de fichier : <ctrl> z Écriture dans le fichier E:\\ ESSAI.TXT On sort de la boucle lorsqu’une fin de fichier ou une donnée incorrecte est saisie. Le destructeur de la classe ofstream ferme le fichier E:\\ ESSAI.TXT. La fonction close() est appelée automatiquement par le destructeur des classes ofstream et ifstream. La fonction Fichier_de_sortie.close() est nécessaire quand le fichier est lu juste après avoir été écrit. Chapitre IX - Gestion de flux

32 Mode d’ouverture de fichier
Mode Description ios::app Écrire toutes les sorties à la fin du fichier. ios::ate Ouvrir un fichier en sortie et se positionner à la fin du fichier (utilisé normalement pour ajouter des données au fichier). Les données peuvent être écrites n’importe où dans le fichier. ios::in Ouvrir un fichier en entrée. ios::out Ouvrir un fichier en sortie. ios::trunc Éliminer le contenu du fichier s’il y en a (c’est l’action par défaut de ios::out). ios::nocreate Si le fichier n’existe pas, l’opération d’ouverture échoue. ios::noreplace Si le fichier existe, l’opération d’ouverture échoue. Note : On peut créer un objet ofstream sans ouvrir de fichier spécifique : ex. : ofstream Fichier_de_sortie; . . . Fichier_de_sortie.open("Donnees.txt", ios::out); Chapitre IX - Gestion de flux

33 Lecture d’un fichier à accès séquentiel
#include <iostream.h> #include <fstream.h> #include <iomanip.h> int main() { ifstream Fichier_entree("E:\\ESSAI.TXT", ios::in); if (!Fichier_entree) cout << "Impossible d'ouvrir le fichier."; return 1; }; int matricule; char nom[20]; float montant; Accès en lecture au fichier D:\\ ESSAI.TXT Ouvrir un fichier en en- trée seule si son contenu ne doit pas être modifié. Détermine si l ’ouverture du fichier a réussi Chapitre IX - Gestion de flux

34 Lecture d’un fichier à accès séquentiel
cout << setiosflags(ios::left) << setw(15) << "Matricule" << setw(15) << "Nom" << "Montant" << endl; while (Fichier_entree >> matricule >> nom >> montant) AfficheLigne(matricule, nom, montant); return 0; // Lorsque la marque de fin de fichier est atteinte, on sort de la // boucle et le fichier est fermé à l’aide du destructeur de ifstream. } void AfficheLigne(int matricule, char nom[20], float montant) { cout << setiosflags(ios::left) << setw(15) << matricule << setw(15) << nom << setw(7) << setprecision(2) << resetiosflags(ios::left) << setiosflags(ios::fixed | ios::showpoint) << montant << endl; Affichage d’une valeur à virgule fixe Force l’affichage du point décimal et des décimales après le point même si elles sont nulles. Chapitre IX - Gestion de flux

35 Chapitre IX - Gestion de flux
Traitement d’un fichier à accès séquentiel en séquence plusieurs fois depuis le début du fichier On peut toujours fermer le fichier et le rouvrir. Les classes istream et ostream fournissent des fonctions membres destinées à repositionner le pointeur de position du fichier (la position en octets de l’octet suivant à lire ou à écrire) : soit fstream fs; fs.seekg(n, ios::beg); Déplace la position de lecture de n positions à partir du début du fichier. fs.seekp(n, ios::beg); Déplace la position d’écriture de n positions à partir du début du fichier. Pour déplacer la position de n caractères à partir de la fin du fichier ou de la position actuelle, servez-vous de ios::end ou ios::cur. Chapitre IX - Gestion de flux

36 Chapitre IX - Gestion de flux
Traitement d’un fichier à accès séquentiel en séquence plusieurs fois depuis le début du fichier fs.tellg(); Retourne la position de lecture actuelle. fs.tellp(); Retourne la position d’écriture actuelle. Un fichier pouvant être de grande taille, les positions sont des entiers longs. Pour connaître le nombre de caractères d’un fichier, fs.seekg(0, ios::end); déplacez la position de lecture à la fin du fichier. long longueur = fs.tellg(); calculez la distance depuis le début du fichier. Chapitre IX - Gestion de flux

37 Lecture et écriture d’un fichier à accès séquentiel : exemple
#include <iostream.h> #include <fstream.h> #include <iomanip.h> class Auto { protected: char Reference[20+1]; char Marque[20+1]; int Prix_vente; public: Chapitre IX - Gestion de flux

38 Chapitre IX - Gestion de flux
Exemple (suite) Auto(char * R = "", char * M = "", int P = 0); /* Permet de créer un objet Auto. Pré - Nil. Post - L'objet Auto est créé en tenant compte des valeurs par défaut pour les différents arguments. */ void Init_Prix_vente(int P); /* Initialise le prix de vente. Pré - L'objet Auto est créé. Post - Le prix de vente est conservé. */ Chapitre IX - Gestion de flux

39 Chapitre IX - Gestion de flux
Exemple (suite) int Acces_Prix_vente(); /* Fournit le prix de vente. Pré - L'objet Auto est créé. Post - Retourne le prix de vente de l'auto. */ char * Acces_Reference(); /* Fournit la référence de l'auto. Post - Retourne la référence de l'auto. */ char * Acces_Marque(); /* Fournit la marque de l'auto. Post - Retourne la marque de l'auto. */ Chapitre IX - Gestion de flux

40 Chapitre IX - Gestion de flux
Exemple (suite) friend ostream & operator << (ostream & out, Auto * v); /* Écriture d'un objet Auto dans un fichier. Pré - L'objet Auto pointé est créé. Post - Les données membres sont écrites dans le fichier. */ friend istream & operator >> (istream & in, Auto * v); /* Lecture des données d'un objet Auto d'un fichier. Post - Les données membres sont lues du fichier. */ }; Chapitre IX - Gestion de flux

41 Chapitre IX - Gestion de flux
Exemple (suite) #include <string.h> #include "Auto.h" Auto::Auto(char * R, char * M, int P) { Prix_vente = P; strcpy(Marque, M); strcpy(Reference, R); } void Auto::Init_Prix_vente(int P) int Auto::Acces_Prix_vente() { return Prix_vente; } char * Auto::Acces_Reference() return Reference; char * Auto::Acces_Marque() return Marque; Chapitre IX - Gestion de flux

42 Chapitre IX - Gestion de flux
Exemple (suite) #include "Auto.h" ostream & operator << (ostream & out, Auto * v) { out << v -> Reference << ';'; out << v -> Marque << ';'; out.precision(6); out << v -> Prix_vente; return out; } Chapitre IX - Gestion de flux

43 Chapitre IX - Gestion de flux
Exemple (suite) istream & operator >> (istream & in, Auto * v) { in.getline(v -> Reference, sizeof(v -> Reference), ';'); in.getline(v -> Marque, sizeof(v -> Marque), ';'); in.width(6); in >> v -> Prix_vente; return in; } Chapitre IX - Gestion de flux

44 Chapitre IX - Gestion de flux
Exemple (suite) void main() { /* Ouverture et construction d'un fichier. */ ofstream Fichier_Ecriture("D:\\Programmation orientée objets \\Chap. IX\\Programmes en C++ \\Liste_autos\\Fichier_auto.TXT"); if (!Fichier_Ecriture) return; Auto * pAuto = NULL; pAuto = new Auto("DX5", "Honda", 12500); Fichier_Ecriture << pAuto; // 1er enregistrement pAuto = new Auto("RX7", "Toyota"); Fichier_Ecriture << pAuto; // 2ième enregistrement pAuto = new Auto("KW7"); Fichier_Ecriture << pAuto; // 3ième enregistrement Chapitre IX - Gestion de flux

45 Chapitre IX - Gestion de flux
Exemple (suite) /* Fermeture du fichier */ Fichier_Ecriture.close(); /* Lecture du fichier et affichage à l'écran. */ ifstream Fichier_Lecture("D:\\Programmation orientée objets \\Chap. IX\\Programmes en C++\ \Liste_autos\\Fichier_auto.TXT"); if (!Fichier_Lecture) return; Chapitre IX - Gestion de flux

46 Chapitre IX - Gestion de flux
Exemple (suite et fin) cout.setf(ios::left, ios::adjustfield); while (!Fichier_Lecture.eof()) { Fichier_Lecture >> pAuto; cout << " Reference : "; cout.width(20); cout << pAuto ->Acces_Reference() << endl; cout << " Marque : "; cout.width(20); cout << pAuto -> Acces_Marque() << endl; cout << " Prix de vente : "; cout << setw(10) << pAuto -> Acces_Prix_vente()<<endl; } Chapitre IX - Gestion de flux

47 Lire et écrire à partir ou vers une chaîne de caractères
La classe istringstream lit des caractères depuis une chaîne (string). La classe ostringstream écrit des caractères vers une chaîne (string). Ces classes de flux sont définies dans l’entête sstream. Exemple : Une chaîne contient une date que vous voulez séparer en jour, mois et année. #include <iostream> void main() #include <sstream> { #include <string> string entree = "23 janvier 1995"; using namespace std; istringstream instr(entree); int jour; string mois; int annee; instr >> jour >> mois >> annee; cout << jour << mois << annee; } *

48 Lire et écrire à partir ou vers une chaîne de caractères
Exemple : Convertir une chaîne contenant des chiffres en sa valeur entière. * int string_vers_int(string s) { istringstream instr(s); int n; instr >> n; return n; } void main() string entree = "1995"; int n = string_vers_int(entree); cout << n;

49 Lire et écrire à partir ou vers une chaîne de caractères
Exemple : Convertir un entier en une chaîne de caractères. * string int_vers_string(int n) { ostringstream s; s << n; return s.str(); } void main() int n = 1955; string s = int_vers_string(n); cout << s;

50 Lire et écrire à partir ou vers une chaîne de caractères
Exemple : Construire une chaîne composée du jour, du mois et de l’année. int jour = 23; string mois = "janvier"; int annee = 1955; ostringstream s; s << jour << "  " << mois << "  " << annee; string sortie = s.str();

51 Lire et écrire à partir ou vers une chaîne de caractères
Exemple : Accepter une entrée (un temps) sur une ligne pour l’analyser en détail. Cette ligne se compose d’un nombre, éventuellement suivi d’un deux points et d’un autre nombre, éventuellement suivi de am ou pm. void lecture_temps(int & heures, int & minutes) string suffixe; { entree >> suffixe; string ligne; if (suffixe == "pm ") getline(cin, ligne); heures =+ 12; istringstream entree(ligne); } entree >> heures; minutes = 0; char ch; entree.get(ch); if (ch == ':') entree >> minutes; else entree.unget(); // Je ne voulais pas // lire ce caractère.

52 Fichier à accès aléatoire
Les données mises en forme et écrites dans un fichier séquentiel ne peuvent être modifiées sans risquer de détruire les autres données du fichier. Ex. : Si chaque enregistrement d’un fichier renferme une chaîne de caractères, la longueur de cette chaîne peut varier d’un enregistrement à l’autre. Une mise à jour peut entraîner la destruction de données de l’enregistrement suivant. On peut effectuer la mise à jour en recopiant le fichier séquentiel mais cela exige de traiter tous les enregistrements pour en modifier un seul. Pour pallier à ceci, on introduit les fichiers à accès aléatoire ou fichiers à accès direct.

53 Fichier à accès aléatoire
But : Les fichiers à accès séquentiel sont inadaptés pour accéder à des emplacements spécifiques d’un fichier. Ex.: Un système de réservation de billets d’avions. L’accès à votre compte bancaire. On a besoin d’un accès direct sans avoir à chercher parmi les autres enregistrements. Note : Seul les fichiers sur disque prennent en charge l’accès aléatoire. Les flux cin et cout en sont incapables.

54 Fichier à accès aléatoire
La technique la plus simple pour créer des fichiers à accès aléatoire consiste à imposer à chaque enregistrement du fichier la même longueur fixe. Cela permet de calculer exactement la position d’un enregistrement en fonction de la clé et de la taille de celui-ci p/r au début du fichier. Les données peuvent alors être insérées dans un fichier à accès aléatoire sans détruire les autres données du fichier. Les données stockées précédemment peuvent également être mises à jour ou supprimées, sans devoir pour autant réécrire la totalité du fichier. La fonction membre write de ostream permet d’écrire un nombre fixe d’octets commençant à un emplacement spécifique en mémoire. On a l’équivalent avec read de istream.

55 Création d’un fichier à accès aléatoire
#include <iostream.h> #include <fstream.h> #include <iomanip.h> struct donnee { int matricule; char nom[20]; float montant; };

56 Création d’un fichier à accès aléatoire
int main() { ofstream Fichier_entree("E:\\DONNEES.TXT", ios::out); if (!Fichier_entree) cout << "Impossible d'ouvrir le fichier."; return 1; }; donnee client; cout << "Entrez matricule, nom et montant :" << endl; while(cin >> client.matricule >> client.nom >> client.montant) Fichier_entree.write(reinterpret_cast<const char *>(&client), sizeof(donnee)); } return 0; Convertit l’adresse de client en un const char * en utilisant l’opérateur de forçage.

57 Mise à jour aléatoire d’un fichier à accès aléatoire
int main() { ofstream Fichier_entree("E:\\DONNEES.TXT", ios::ate); if (!Fichier_entree) cout << "Impossible d'ouvrir le fichier."; return 1; }; donnee client; int numero; Fichier_entree.seekp(0, ios::end); long longueur = Fichier_entree.tellp(); int nb = longueur / sizeof(donnee); Mise à jour du fichier n’importe où. nombre d’enregistrements

58 Mise à jour aléatoire d’un fichier à accès aléatoire
do { cout << "Entrez le no. de l'enregistrement (1 - " << nb << "): " << endl; cin >> numero; } while (numero <= 0 || numero > nb); cout << "Entrez matricule, nom et montant :" << endl; cin >> client.matricule >> client.nom >> client.montant; Fichier_entree.seekp((numero - 1) * sizeof(donnee)); // positionnement adéquat dans le fichier. Fichier_entree.write(reinterpret_cast<const char *>(&client),sizeof(donnee)); return 0; }

59 Lecture séquentielle d’un fichier à accès aléatoire
#include <iostream.h> #include <fstream.h> #include <iomanip.h> struct donnee { int matricule; char nom[20]; float montant; }; void AfficheLigne(ostream & sortie, const donnee & c) sortie << setiosflags(ios::left) << setw(15) << c.matricule << setw(15) << c.nom << setw(7) << setprecision(2) << resetiosflags(ios::left) << setiosflags(ios::fixed | ios::showpoint) << c.montant << '\n'; }

60 Lecture séquentielle d’un fichier à accès aléatoire
int main() { ifstream Fichier_entree("E:\\DONNEES.TXT", ios::in); if (!Fichier_entree) cout << "Impossible d'ouvrir le fichier."; return 1; }; donnee client; cout << setiosflags(ios::left) << setw(15) << "Matricule" << setw(15) << "Nom" << setw(7) << "Montant" << endl; Fichier_entree.read(reinterpret_cast<char *>(&client), sizeof(donnee)); while (Fichier_entree && ! Fichier_entree.eof()) AfficheLigne(cout, client); return 0; } Ouverture en entrée Détecte si une erreur se produit à la lecture.


Télécharger ppt "Chapitre IX Gestion de flux."

Présentations similaires


Annonces Google