chapitre ix gestion de flux. chapitre ix - gestion de flux2 généralités sur les flux un flux ou...

60
Chapitre IX Chapitre IX Gestion de flux

Upload: adelard-lang

Post on 04-Apr-2015

111 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IXChapitre IX

Gestion de flux

Page 2: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

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 êtremanipulé à la fois en lecture et en écriture.

Offre une transparence vis-à-vis de la source ou de la destination des donnéesc’est-à-dire

un programme peut utiliser les mêmes instructions de manipulation de fluxpour tous les types de flux de sortie (écran, fichier, mémoire)pour tous les types de flux d’entrée (clavier, fichier, mémoire).

Ex.: 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.

En C++, tous les flux sont symbolisés par des classes qui font partie de la librairieiostream (input-output stream, pour flux d’entrées/sorties).

Page 3: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

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éessous la forme d’une arborescence:

iosclasse de base qui regroupe les

caractéristiques communesaux flux

istream ostreamclasse de base duflux d’entrée

classe de base duflux de sortie

ifstream iostream ofstream flux de sortie sur fichierflux d’entrée

sur fichier

canaux standards

Page 4: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 4

Généralités sur les fluxToutes 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 classeostream (ou dérivée).

L’opérande de gauche de l’opérateur >> doit correspondre à un objet de la classeistream (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 *.

On peut donc lire et écrire des variables de ces différents types de donnéesà l’aide de ces 2 opérateurs.

comme par exemple, ostream & operator << (ostream & out, char valeur);

Page 5: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 5

Généralités sur les fluxC++ 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) (dérivée de la classe ostream)

clog: permet à la fois d’envoyer des messages d’erreursvers la sortie erreur standard (écran par défaut)

et de remplir un fichier de log (fichier d’alerte) (dérivée de la classe ostream)

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.

Page 6: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 6

Affichage à l’écran avec cout

Ex.: int entier = 12;……cout << "  Entier : "  << entier << '\n';

saut de ligne

La librairie iostream fournit un certain nombre de mots clés qui permettent demodifier les caractéristiques d’un flux.

Syntaxe: cout << manipulateur;

Le padding consiste à compléter, généralement avec des espaces ou des zéros,un élément affiché à l’écran.

Page 7: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 7

Affichage à l’écran avec coutdec Convertir en base décimale hex Convertir en base hexadécimale oct Convertir en base octale ws Supprimer les espaces endl Ajouter un saut de ligne en fin de flux ends Ajouter un caractère de fin de chaîne flush Vide un flux de sortie setbase(int n) Choisir la base (0, 8, 10 et 16). La valeur 0

correspond à la valeur par défaut (décimal). setfill(int c) Choisir le caractère de remplissage (« padding ») setprecision(int n) Indiquer le nombre de chiffres d’un nombre

décimal setw(int n) Définir la largeur du prochain champ de sortie :

facilite l’alignement. Ex. : cout << setw(8);

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é.

Page 8: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 8

Affichage à l’écran avec cout

fill() Renvoyer le caractère de remplissagefill(char c) Modifier le caractère de remplissageprecision() Renvoyer la précision pour les nombres décimauxprecision(int n) Modifier la précision pour les nombres décimauxsetf(long flag) Modifier une propriété de formatagesetf(long flag, long champ)

Modifier une propriété de formatage d’un champd’activité particulier

width() Renvoyer la largeur d’affichagewidth(int n) Modifier la largeur d’affichage

Méthode Objectif

Les méthodes de la classe ios

Page 9: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 9

Affichage à l’écran avec cout

Ex.: Utilisation de la fonction setf() pour modifier l’alignement des colonnes affichéesi.e. choisir d’aligner à gauche ou à droite les éléments affichés.

cout.setf(ios::right, ios::adjustfield);cout << setw(12) << "AAA" << endl;cout << setw(12) <<   "BBBBBB" << endl;

AAABBBBBB

alignement à droite

sous réserve que lataille d’affichage soit

spécifiée

Alignement à gauche: cout.setf(ios::left, ios::adjustfield);

Page 10: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

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;

ConversionsEntier : 15Hexa : fOct : 17

On repasse en base décimale.

Page 11: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

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 : 10.25Decimal : 110.25Decimal : 1010.25Decimal : 00010.25

Page 12: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 12

Affichage à l’écran avec cout

Ex.: float PI = 3.14159;……..cout << "PI : " << PI << endl;cout << "PI : " << setprecision(3) << PI << endl;cout << "PI : " << setprecision(4) << PI << endl;cout << "PI : " << setprecision(5) << PI << endl;

PI : 3.14159PI : 3.14PI : 3.142PI : 3.1416

Page 13: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

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.-------

Page 14: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 14

Saisir au clavier avec cinSaisir au clavier avec cinL’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;

Page 15: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 15

Saisir au clavier avec cinSaisir au clavier avec cin

Puisque l’espace sert à séparer les valeurs d’une saisie multiple, on ne peut saisirde 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 nombrede 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.

La variable sera considérée invalide uniquement à l’issue de la saisie.

Il est donc possible de saisir des caractères dans une variable entière.

Page 16: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 16

Saisie de chaînes au clavier et Saisie de chaînes au clavier et nombre de caractèresnombre de caractères

char chaine[5+1];…...cout << "Saisissez une chaine de caracteres: " ;cin >> chaine;

Écrasez l’espace aprèsle tableau chaine.

Danger

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.

Page 17: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 17

Saisie de chaînes au clavier Saisie de chaînes au clavier incluant des espacesincluant des espaces

La classe istream contient la fonction membre getline() qui permet de saisir deschaî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 classeistream

chaîne à saisir

# max. de caractèresà saisir + '\n'

caractère qui représenterala fin de la saisie

Page 18: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 18

Saisie de chaînes au clavier Saisie de chaînes au clavier incluant des espacesincluant des espaces

Ex.: #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));…….

}……

Page 19: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 19

Redéfinition des opérateurs de Redéfinition des opérateurs de fluxflux

Les 2 opérateurs << et >> ont été surchargés pour les types primaires du langage etles 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 lalibrairie iostream exactement comme les types primaires ou les chaînes de caractères.

Page 20: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 20

Redéfinition des opérateurs de Redéfinition des opérateurs de fluxflux

TRAME

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 >>pourront accéder à tous les

membres de MaClasse.

<< et >>peuvent être utilisés avec l’adresse ou la référence d’un objet

de type MaClasse.

Page 21: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

21

Redéfinition des opérateurs de Redéfinition des opérateurs de fluxflux

TRAME

ostream& operator << (ostream& out, MaClasse * v){

…….return out;

}istream& operator >> (istream& in, MaClasse& v){

…….return in;

}……..

référence à un objet de typeostream

pointeur à un objet de typeMaClasse

Dès que << sera utilisé aveccomme opérande de gaucheun objet de type ostream etcomme opérande de droite unobjet 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.

L’appel par valeur n’est pas permis.

Page 22: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 22

Redéfinition des opérateurs de Redéfinition des opérateurs de fluxflux

Ex. tiré de Stéphane Dupin, Le langage C++, 1999, pp. 340-343.

#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);

};

Page 23: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 23

Redéfinition des opérateurs de Redéfinition des opérateurs de fluxflux

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;

}

Page 24: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 24

Redéfinition des opérateurs de Redéfinition des opérateurs de fluxflux

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;}

Page 25: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 25

Redéfinition des opérateurs de Redéfinition des opérateurs de fluxflux

Voiture : Marque : Lotus Modele : Seven Prix : 300000

Saisissez la marque le modele et le prix :Marque : Aston MartinModele : DB7Prix : 600000

Resultat : Marque : Aston Martin Modele : DB7 Prix : 600000

Page 26: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 26

Redéfinition des opérateurs de Redéfinition des opérateurs de fluxflux

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;

}

Dans le cas où nous avons à réaliser une opération dans le cas d’un pointeur vers laclasse, on procède ainsi:

Page 27: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 27

Redéfinition des opérateurs de Redéfinition des opérateurs de fluxflux

La possibilité de surcharger ces opérateurs facilite l’extension du langage à denouveaux 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";

Page 28: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 28

Redéfinition des opérateurs de Redéfinition des opérateurs de fluxflux

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.

Page 29: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 29

Lire et écrire à partir ou vers Lire et écrire à partir ou vers un fichierun fichier

Toutes les opérations de gestion de flux étudiées peuvent s’appliquer à la gestionde fichiers.

Il suffit de créer un objet de type ofstream pour écrire dans un fichierun objet de type ifstream pour lire un fichier.

Ces 2 classes sont déclarées dans le fichier d’en-tête fstream.h etelles 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ésdans un ordre imposé par un champ de clé de l’enregistrement.

Fichiers à accès aléatoire

On peut supposer que l’utilisateur introduise les enregistrementsdans l’ordre du champ de clé ou prévoir un tri automatique.

Page 30: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 30

Création d’un fichier à accès séquentielCré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 fichierE:\\ ESSAI.TXT

Détermine si l ’ouverture du fichier

a réussi

Mode d’ouverture par défaut dufichier pour écrire des données.

Les fichiers existants ouverts avec le mode iossont tronqués, i.e. toutes les données sont éliminées.

Si le fichier n’existe pas encore, il est créé.

Page 31: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 31

Création d’un fichier à accès séquentielCréation d’un fichier à accès séquentielcout << "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;}

Écriture dans le fichierE:\\ ESSAI.TXT

Le destructeur de la classe ofstream ferme le fichier E:\\ ESSAI.TXT.

La fonction close() est appelée automatiquement par le destructeur des classesofstream et ifstream.

La fonction Fichier_de_sortie.close() est nécessaire quand le fichier est lu justeaprès avoir été écrit.

Fin de fichier : <ctrl> z

On sort de la bouclelorsqu’une fin de fichierou une donnée incorrecteest saisie.

Page 32: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 32

Mode d’ouverture de fichierMode d’ouverture de fichierMode 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);

Page 33: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 33

Lecture d’un fichier à accès séquentielLecture 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 fichierD:\\ ESSAI.TXT

Détermine si l ’ouverture du fichier

a réussi

Ouvrir un fichier en en-trée seule si son contenune doit pas être modifié.

Page 34: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 34

Lecture d’un fichier à accès séquentielLecture d’un fichier à accès séquentielcout << 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 desdécimales après le point même si elles sont nulles.

Page 35: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 35

Traitement d’un fichier à accès Traitement d’un fichier à accès séquentiel en séquence plusieurs fois séquentiel en séquence plusieurs fois

depuis le début du fichierdepuis le début du fichierOn 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’octetsuivant à lire ou à écrire) :

soit fstream fs;

fs.seekg(n, ios::beg); Déplace la position de lecture de npositions à partir du début du fichier.

fs.seekp(n, ios::beg); Déplace la position d’écriture de npositions à partir du début du fichier.

Pour déplacer la position de n caractères à partir de la fin du fichierou de la position actuelle, servez-vous de ios::end ou ios::cur.

Page 36: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 36

Traitement d’un fichier à accès Traitement d’un fichier à accès séquentiel en séquence plusieurs fois séquentiel en séquence plusieurs fois

depuis le début du fichierdepuis le début du fichierfs.tellg(); Retourne la position de lecture actuelle.

fs.tellp(); Retourne la position d’écriture actuelle.

Un fichier pouvant être de grande taille, les positions sontdes 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.

Page 37: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 37

Lecture et écriture d’un fichierLecture et écriture d’un fichierà accès séquentiel : exempleà 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:

Page 38: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 38

ExempleExemple (suite) (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é. */

Page 39: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 39

ExempleExemple (suite) (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.

Pré - L'objet Auto est créé.Post - Retourne la référence de l'auto. */

char * Acces_Marque();/* Fournit la marque de l'auto.

Pré - L'objet Auto est créé.Post - Retourne la marque de l'auto. */

Page 40: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 40

ExempleExemple (suite) (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.

Pré - L'objet Auto pointé est créé.Post - Les données membres sont lues du fichier. */

};

Page 41: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 41

ExempleExemple (suite) (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){

Prix_vente = P;}

int Auto::Acces_Prix_vente(){

return Prix_vente;}char * Auto::Acces_Reference(){

return Reference;}char * Auto::Acces_Marque(){

return Marque;}

Page 42: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 42

ExempleExemple (suite) (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;}

Page 43: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 43

ExempleExemple (suite) (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;}

Page 44: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 44

ExempleExemple (suite) (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 enregistrementpAuto = new Auto("RX7", "Toyota");Fichier_Ecriture << pAuto; // 2ième enregistrementpAuto = new Auto("KW7");Fichier_Ecriture << pAuto; // 3ième enregistrement

Page 45: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 45

ExempleExemple (suite) (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;

Page 46: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

Chapitre IX - Gestion de flux 46

ExempleExemple (suite et fin) (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;

}}

Page 47: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

47

Lire et écrire à partir ou vers Lire et écrire à partir ou vers une chaîne de caractèresune 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 etanné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;

}

*

Page 48: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

48

Lire et écrire à partir ou vers Lire et écrire à partir ou vers une chaîne de caractèresune 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;

}

*

Page 49: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

49

Lire et écrire à partir ou vers Lire et écrire à partir ou vers une chaîne de caractèresune 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;

}

*

Page 50: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

50

Lire et écrire à partir ou vers Lire et écrire à partir ou vers une chaîne de caractèresune 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();

Page 51: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

51

Lire et écrire à partir ou vers Lire et écrire à partir ou vers une chaîne de caractèresune chaîne de caractères

Exemple : Accepter une entrée (un temps) sur une ligne pour l’analyser en détail.

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();

Cette ligne se compose d’un nombre, éventuellement suivi d’un deux points et d’unautre nombre, éventuellement suivi de am ou pm.

// Je ne voulais pas// lire ce caractère.

Page 52: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

52

Fichier à accès aléatoireFichier à accès aléatoire

Les données mises en forme et écrites dans un fichier séquentiel ne peuvent êtremodifié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éesde l’enregistrement suivant.

On peut effectuer la mise à jour en recopiant le fichier séquentiel mais cela exigede 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.

Page 53: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

53

Fichier à accès aléatoireFichier à accès aléatoire

But : Les fichiers à accès séquentiel sont inadaptés pour accéder à des emplacementsspécifiques d’un fichier.

Note : Seul les fichiers sur disque prennent en charge l’accès aléatoire.Les flux cin et cout en sont incapables.

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 à chercherparmi les autres enregistrements.

Page 54: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

54

Fichier à accès aléatoireFichier à 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 fonctionde 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éatoiresans détruire les autres données du fichier.

La fonction membre write de ostream permet d’écrire un nombre fixe d’octetscommençant à un emplacement spécifique en mémoire.On a l’équivalent avec read de istream.

Les données stockées précédemment peuvent également être mises à jour ousupprimées, sans devoir pour autant réécrire la totalité du fichier.

Page 55: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

55

Création d’un fichier à accès aléatoireCré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;

};

Page 56: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

56

Création d’un fichier à accès aléatoireCréation d’un fichier à accès aléatoireint 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.

Page 57: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

57

Mise à jour aléatoireMise à jour aléatoired’un fichier à accès aléatoired’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 à jourdu fichier

n’importe où.

nombred’enregistrements

Page 58: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

58

Mise à jour aléatoireMise à jour aléatoired’un fichier à accès aléatoired’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;

}

Page 59: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

59

Lecture séquentielleLecture séquentielled’un fichier à accès aléatoired’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';

}

Page 60: Chapitre IX Gestion de flux. Chapitre IX - Gestion de flux2 Généralités sur les flux Un flux ou canal de données représente un ensemble de données pouvant

60

Lecture séquentielleLecture séquentielled’un fichier à accès aléatoired’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);Fichier_entree.read(reinterpret_cast<char *>(&client), sizeof(donnee));

};return 0;

}

Ouvertureen entrée

Détecte si uneerreur se produità la lecture.