68
Structures de données IFT-2000 Abder Alikacem Abder Alikacem Les entrées/sorties en C++ Département d’informatique et de génie logiciel Édition Septembre 2009

Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Embed Size (px)

Citation preview

Page 2: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Plan

• Les fonctions d’entrée/sortie• Les manipulateurs• Les sorties formatées• Les fonction d’entrée/sortie avec les fichiers• Strings et streams

Page 3: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Les fonctionnalités d'entrées / sorties en C++ sont orientées objet. Elles sont gérées par le biais d’un ensembles de type (classes) spécialisés, les flots (streams).

L’idée de base des flots est de séparer l’aspect logique des entrées-sorties (i.e. leur intégration dans des programmes) de leur aspect physique (i.e. leur réalisation par le biais de périphériques particuliers).

Ainsi, un flot représente un flux de données entre le programmeet un dispositif d’entrée-sorties externe (écran, imprimante, ...) ou un fichier.

La librairie standard <iostream> permet de faire des entrées-sorties par flots. Notons que pour obtenir de meilleures performances, un tampon mémoire, par lequel les données transitent, est par défaut associé à chaque flot.

Page 4: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

La famille des iostream Une stream en C++ : séquence de caractères permettant de faire les opérations d'entrées/sorties.

Une ostream gère les sorties inclut la définition de l'opérateur d’insertion <<. Une istream gère les entrées inclut la définition de l'opérateur d’extraction >>.

ios

iostream

istream ostream

Page 5: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

La famille des iostream

Une ostream peut être redirigée vers :• l'écran (cout), la console d'erreur (cerr),• le fichier d'historique (clog),• un fichier (ofstream),• un espace en mémoire (ostringstream,

ostrstream).

Une istream peut être redirigée vers :• le clavier (cin),• un fichier (ifstream),• un espace en mémoire (istrstream).

Page 6: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

<iostream> est plus sûr du point de vue typage que <stdio.h> du C, est moins source d'erreurs, améliore les performances, est extensible, et enfin que certaines des classes qui le composent peuvent être sous-classées.

Plus sûre du point de vue typage: avec <iostream.>, le type de l'objet sujet à une E/S est connu statiquement par le compilateur. <stdio.h> utilise lui les champs "%" pour connaître dynamiquement le type de l'objet.

Moins sources d'erreurs: avec <iostream.>, il n'est pas nécessaire d'utiliser ces champs "%", qui sont redondants et qui doivent être consistants avec l'objet effectivement sujet à l'E/S. Enlever cette redondance élimine toute une catégorie d'erreurs possibles.

Extensibles: les mécanismes C++ de <iostream.h> permetttent à l'utilisateur de définir de nouveaux types qui pourront être sujets à des E/S, et ce sans casser le code existant. Imaginez le chaos que ça créerait si chacun ajoutait ses propres champs, incompatibles, "%" à printf() et à scanf()!.

Page 7: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Les principales conséquences dans l'utilisation des flots sont:

vitesse d'exécution plus rapide vérification de type : pas d'affichage erroné on peut utiliser les flux avec les types utilisateurs

Sous-classables: les mécanismes C++ de <iostream.h> sont construits sur des classes, comme par exemple ostream et istream. À la différence du FILE* de <stdio.h>, ce sont de vraies classes et elles sont de ce fait sous-classables. Cela signifie que vous pouvez avoir vos propres types utilisateur, qui ressemblent à des flots (streams) et qui agissent comme tels, mais qui font aussi toutes les choses étranges et merveilleuses que vous avez décidé. Vous accédez automatiquement à des tonnes de code d'E/S écrits par des utilisateurs que vous ne connaissez même pas, utilisateurs qui eux-mêmes n'ont rien besoin de connaître de votre classe de "flot étendu".

Page 8: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Les flots de sorties (de type std::ostream) sont std::cout et std::cerr pour le standard et l’erreur respectivement. Le flot d’entrée (de type std::istream) est std::cin. Comme l’indique le préfixe std::, tous ces objets sont dans le namespace std.

• cin : flot lié à l’entrée standard, qui par défaut est le clavier• cout : flot lié à la sortie standard, qui par défaut est la console• cerr : flot lié à la sortie d’erreur standard, qui par défaut est la console

Les opérations de sorties sont réalisées à l’aide de l’opérateur d’insertion « << », tandis que celle d’entrées le sont à l’aide de l’opérateur d’extraction, « >> ».

Page 9: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Par exemple, l'écriture à l'écran de la valeur d’une expression se traduit par le code suivant :

cout << expression;

cout << "Bonjour"; //Affiche Bonjour

Cela sous entend la surcharge de l'opérateur << pour le type de donnée correspondant à expression.

Ce travail a été réalisé pour la plupart des types de base du C++. Il vous appartiendra de le faire pour vos propres classes (surcharge desopérateurs << et >>).

Page 10: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

iostream bibliothèque C++ des flots stdio.h istream flot d ‘entrée –ostream flot de sortie -<< opération de sortie printf >> opération d ‘entrée scanf cin flot entrée standard stdin cout flot de sortie standard stdout cerr flot de sortie des erreurs stderr clog flot de sortie des erreurs -endl fin de ligne ” \n ‘

C++ Description C

Le concept de flots d’octets

Page 11: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Le concept de flots d’octets

Les opérateurs << et >> sont génériques. On peut mélanger les types.

short s = 1; int i = 2; long l = 3; float f= 4.5; double d = 6.7; cout<<"s= "<<s<<"i= "<<i…"d= "<<d<<endl;

Il n ‘y a plus de chaîne de format à la « printf».

Page 12: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Le concept de flots d’octets

Les opérateurs << et >> sont génériques. Ils sont définis sur les types:

bool, short, int, long float, double char, char*

On doit les redéfinir soi-même pour les types que l ‘on crée si on veut les afficher.

Page 13: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Le concept de flots d’octets

On dispose de manipulateurs spéciaux sur les flots

C++ C syntaxe fait quoi

flush fflush cout << flush; vide le tampon endl \n + fflush cout << endl; fin de ligne hex - cout << hex; hexa oct - cout << oct; octal dec - cout << dec; décimal ws - cin >> ws; élimine blancs

Page 14: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Exemples

int n=2;double f=1.5;char c='z';cout<<n; // afficher un entier sur la sortie standardcout<<f<<endl; // afficher un double et un changement de lignecout<<"n = "<<n; // afficher: n = 2cout<<c; // afficher un caractèrecin >>c; // lire un caractère (saute les espaces)cin.get(c) // lire un caractère (ne saute pas les espaces)cin >>n>>f; // lire un entier puis un doublecerr<<"Erreur"; // afficher un message sur l'erreur standard

Page 15: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Syntaxe pour l’écriture sur la sortie standard (écran)

cout << <expression1> << <expression2> << ... << <expressionn>;

Les opérateurs << sont prévus pour être chaînés. Vous pouvez donc les cumuler sur la même ligne de code, par exemple:

int i; int j; cout << i << " " << j << endl;

La constante symbolique endl vous permet de changer de lignes indépendamment de l'architecture dans laquelle le programe évolue.

Les chaînes de caractères doivent être indiquées entre guillemets anglais «"», tandis que les caractères simples sont eux indiqués entre apostrophes «’».

Les valeurs affichées ne sont, pas délimitées par défaut (pas d’espaces séparateurs). Les délimiteurs sont donc à indiquer explicitement, par exemple par ‘ ‘ ou" ".

Un retour de chariot ( '\n' )

Page 16: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Syntaxe pour la lecture sur l’entrée standard (clavier)

cin << <var1> << <var2> << ... << <varn>;#include <iostream>int main(){

int i;double x;cout << "Valeurs pour i et x: " << flush;cin >> i >> x;cout << "=> " << i << ", " << x << endl;return 0;

}

Le manipulateur flush permet d’assurer l’affichage de la ligne courante, en l’absence de saut de ligne (il ordonne le vidage du tampon d’affichage).

Remarque. cerr n’a pas de tampon mémoire: toutes les données introduites sont immédiatement acheminées vers la sortie d’erreur standard. Il n’est donc pas nécessaire, pour ce flot, de demander explicitement le vidage du tampon mémoire au moyen de flush.

Page 17: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

cin/cout définis dans <iostream> inclure l'entête

cin/cout, les opérateurs << et >> et la classe string définis dans le namespace std.

Dans un .cpp : ajouter au début du fichier using namespace std;

Dans un .h : évitez le using, • utilisez plutôt explicitement le nom du namespace avec ::

using namespace :: cin;usinf namespace:: cout;using namespace :: endl;

Page 18: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

#include <iostream>#include <string>using namespace std;int main(){ cout << "Entrez votre nom : " ; string nom; cin >> nom; cout << "Entrez votre poids (Kg): " ; double poids; cin >> poids; cout << "Bonjour : " << nom << endl; cout << "Votre poids est " << poids << "kilo" << endl; return 0;}

Problème si des espaces. Utilise plutôt un bufferet méthodes de cin.

Page 19: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Des méthodes des iostream

La istream : En plus d'utiliser l'opérateur surchargé >> … méthodes intéressantes

get() ignore() getline().

La ostream : En plus d'utiliser l'opérateur surchargée << … méthodes intéressantes :

precision() width() fill() setf() et unsetf()

Page 20: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

std::istream& get()

Quelques surcharges :

int istream::get() Pour obtenir le code ASCII d'un caractère istream& istream::get(char& c) Pour obtenir un caractère istream& istream::get(char* strP, int dim, char delim = '\n') Pour obtenir une chaîne de caractères d'une dimension déterminée,

ou jusqu'à un caractère de fin, ici par défaut à '\n' prend les espaces mais ne consomme pas le caractère de fin.

Page 21: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

int istream:: get(), pour obtenir le code ASCII d'un caractère.

std::istream& get()

cout << "Entrez un caractère ";int entier = cin.get();cout << "Le code ASCII est : " << entier << endl;

Résultat

Entrez un caractère : ALe code ASCII est : 65

Page 22: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

istream& istream::get(char& c), pour obtenir un caractère dans le paramètre c.

std::istream& get() #include <iostream>

using namespace std;int main(){

char unChar;cout << "Entrez un caractere [. pour quitter]: ";cin.get(unChar);while (unChar != '.'){

if (cin){

cout << "Le caractere est : " << unChar<< endl << endl;

}// --- On consomme la fin de lignecin.get();cout << "Entrez un caractere [. pour quitter]: ";cin.get(unChar);

}return 0;

}

Page 23: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

std::istream& get()

istream& istream::get(char* strP, int dim, char delim = '\n'), pour obtenir une chaîne de caractères d'une dimension déterminée ou jusqu'à un caractère de fin, ici par défaut à '\n'.

Prend les espaces mais ne consomme pas le caractère de fin.

Si dimension dépassée les caractères supplémentaires resteront dans la stream jusqu'au délimiteur.

Il faut gérer cette possibilité : vider la stream de ses caractères.

Page 24: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

std::istream& get()

#include <iostream>using namespace std;int main(){

char buffer[11];cout << "Entrez une chaine [. pour quitter]: ";cin.get(buffer, 10);while (strcmp(buffer, ".") != 0){

if (cin){

cout << "La chaine de caractères est : "<< buffer << endl;

}cin.get(); // On consomme la fin de ligne car non récupéré de la

stream.cout << "Entrez une chaine [. pour quitter]: ";cin.get(buffer, 10);

}return 0;

}

Page 25: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

std::istream& get()

Résultat:Entrez une chaîne [. pour quitter] : Jean-LucLa chaîne de caractères est : Jean-LucEntrez une chaîne [. pour quitter] : Jean-Luc BoutinLa chaîne de caractères est : Jean-Luc B //Prend seulement 10 caractères

Entrez une chaîne [. pour quitter] :La chaîne de caractères est : utin //Le 'o' est consommé par cin.get()

//et "utin" est immédiatement affiché.

Entrez une chaîne [. pour quitter] :

Page 26: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

std::ostream& put()

La fonction symétrique de get() est put()

int main() { char c; while(cin.get(c)) cout.put(c); return 0;}

Page 27: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

std::istream& ignore()

Pour enlever les caractères non désirés dans la stream :

istream::ignore()

Par défaut, ignore() sans paramètre est l'équivalent de get().

Permet de spécifier le nombre maximal de caractères à enlever ainsi que la condition de fin ou délimiteur, par défaut à '\n'.

Choisir un nombre arbitrairement grand pour s'assurer de vider la stream avant de continuer.

Page 28: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

std::istream& ignore()

#include <iostream>using namespace std;int main(){

char buffer[11];cout << "Entrez une chaine [. pour quitter]: ";cin.get(buffer, 10);while (strcmp(buffer, ".") != 0){

if (cin){

cout << "La chaine de caractères est : "

<< buffer << endl;}// --- On consomme tous les caractères

laissés dans// --- la stream jusqu'à la fin de ligne.cin.ignore(100, '\n');

cout << "Entrez une chaine [. pour quitter]: ";

cin.get(buffer, 10);}return 0;

}

Page 29: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

std::istream& ignore()

Résultat:Entrez une chaîne [. pour quitter] : Jean-LucLa chaîne de caractères est : Jean-LucEntrez une chaîne [. pour quitter] : Jean-Luc BoutinLa chaîne de caractères est : Jean-Luc BEntrez une chaîne [. pour quitter] : // Les autres caractères ont été

// consommés par la méthode // istream::ignore(100).

Page 30: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

std::istream& getline()

permet de lire une ligne entière ou la dimension du buffer.

istream& getline(char* strP, int dim, char c = '\n');

Permet donc de lire une ligne sans avoir à s'occuper de la fin de ligne.

La fin de ligne est consommée par la méthode.

Il faut disposer de suffisamment de mémoire pour lire la ligne :256, 512 ou 1024 caractères ou plus selon les besoins.

Page 31: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

std::istream& getline()

La fonction getline() permet donc de lire une ligne complète, séparateurs compris.

const int MAX = 10; int main() { char t[MAX]; while(cin.getline(t, MAX, ‘\n‘)) cout << t << endl; return 0;}

Page 32: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

std::istream& getline()

#include <iostream>using namespace std;int main(){

char buffer[256];cout << "Entrez le point [.] pour quitter : ";cin.getline(buffer, 255);

while (cin && strcmp(buffer, ".") != 0){

if (cin){

cout << "La chaine de caractères est : "<< buffer << endl;

}

cout << "Entrez le point [.] pour quitter : ";cin.getline(buffer, 255);

}return 0;

}

Page 33: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

std::istream& getline()

Résultat:Entrez une chaîne [. pour quitter] :Voici une longue phrase sur une ligne...La chaîne de caractère est :Voici une longue phrase sur une ligne...Entrez une chaîne [. pour quitter] :Voici une autre longue phrase sur une ligne ...La chaîne de caractère est :Voici une autre longue phrase sur une ligne ...Entrez une chaîne [. pour quitter] :

Page 34: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

ostream::width()

Permet de spécifier la largeur du champ à afficher.Par défaut, l'alignement est à droite.

L'application de la méthode width() ne tient que pour le prochain champ à afficher.

Si on veut que cela s'applique à tous les prochains champs àafficher :

appeler la méthode width() avant d'afficher chaque champ.

Si la largeur du champ n'est pas suffisante pour afficher lechamp,

le C++ ne tient pas compte de la largeurla donnée est plus importante que sa présentation...

Page 35: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

ostream:: width()

Exemples

// --- Appel une seule fois avant d'afficher les champscout.width(10);for (int i=0; i<3; i++){cout << 123 << endl;}cout << endl;// --- Appel à chaque affichage d'un champfor (int j=0; j<3; j++){cout.width(10);cout << 321 << endl;}cout << endl;

Résultat 123123123

321 321 321

Page 36: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

ostream:: width()

Exemples

cout << "--------------------" << endl;cout.width(5);cout << 123;cout.width(7);cout << 543;cout.width(3);cout << 4;cout.width(5);cout << 9876 << endl;//Il y aura décalage, à cause de la largeur du 1er champ.cout.width(5);cout << 123456;cout.width(7);cout << 543;cout.width(3);cout << 4;cout.width(5);cout << 9876 << endl;

Résultat[---][-----][-][---]-------------------- 123 543 4 9876123456 543 4 9876

Page 37: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

ostream::precision()

Permet de contrôler le nombre de chiffres significatifs visibles à l'affichage.

Par défaut : 6 chiffres significatifs.

On peut spécifier le nombre de chiffres significatifs désirés.

Un appel de precision() est valide jusqu'à ce que la précision soit changée.

Page 38: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

ostream::precision()

int i;double valeurs[5];valeurs[0] = 54.354;for (i=1; i<5; i++){

valeurs[i] = valeurs[i-1] * 0.10;}cout << "Affichage avec la précision par défaut" << endl;for (i=0; i<5; i++){

cout.width(10);cout << valeurs[i] << endl;

}cout << "Affichage avec précision(3)" << endl;cout.precision(3);for (i=0; i<5; i++){

cout.width(10);cout << valeurs[i] << endl;

}

RésultatAffichage avec la précision par défaut

54.3545.43540.54354

0.0543540.0054354

Affichage avec précision(3)54.45.44

0.5440.05440.00544

Page 39: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

ostream::fill()

Permet de spécifier le caractère de remplissage qui peut être ajouté dans les champs affichés.

Par défaut : un espace.

Pour changer temporairement le caractère de remplissage, fill() :

retourne le caractère courant de remplissageprend en paramètre celui en remplacement :

char ostream::fill(char fill)

Si on conserve l'ancien caractère, on peut restaurer l'état de la stream après usage.

Page 40: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

ostream::fill()

int i;double valeurs[5];valeurs[0] = 54.354;for (i=1; i<5; i++){

valeurs[i] = valeurs[i-1] * 0.10;}cout << "Remplissage de l'espace libre avec des *" << endl;char f = cout.fill('*');for (i=0; i<5; i++){

cout.width(10);cout << valeurs[i] << endl;

}cout << "Restauration du remplissage précédent" << endl;cout.fill(f);for (i=0; i<5; i++){

cout.width(10);cout << valeurs[i] << endl;

}

Résultat:Remplissage de l'espace libre avec des *

******54.4******5.44*****0.544****0.0544***0.00544

Restauration du remplissage precedent54.45.44

0.5440.05440.00544

Page 41: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

ostream::setf() et ostream::unsetf()

Objet de type ostream :maintient des états dans un entier où chaque bit représentequelque chose.

On peut activer un état avec setf() ou le désactiver avec unsetf().plusieurs états (format flags)Pouvant être contrôlés par ces deux méthodes.

Exemple intéressant :comment conserver plusieurs renseignements dans un seul

entier.Chaque bit de l'entier correspond à un état.En faisant un OU binaire sur l'entier, on arrive à activer oudésactiver le ou les états désirés.

Page 42: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Quelques états intéressants

ios::left :alignement sur la gauche avec remplissage sur la droite.

ios::right :alignement par défaut avec remplissage sur la gauche.

ios::fixed :affichage des réels en format fixe.

ios::scientificaffichage des réels en format scientifique.

ios::showposaffichage du signe positif

Il existe d'autres états!

Page 43: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Exemples

// Alignement à gauche, format scientifique, signe positif,// précision 8 chiffres après le point, champs de largeur 20 caractères.cout.setf(ios::left | ios::scientific | ios::showpos);cout.precision(8);cout.width(20);cout << 3457.891234 << endl;cout.width(20);cout << -3457.891234 << endl;// --- Enlève le signe positif// --- Alignement à droite, format fixe, précision 8 chiffres total,// --- champs de largeur 20 caractères.cout.unsetf(ios::showpos);cout.setf(ios::right | ios::fixed);cout.precision(8);cout.width(20);cout << 3457.891234 << endl;cout.width(20);cout << -3457.891234 << endl;

Résultat+3.45789123e+003-3.45789123e+003 3457.8912 -3457.8912

Page 44: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Autres fonctions de flots

eof() fin de fichierfail() erreurbad() problème gravegood() pas de problèmeclear() annule les problèmes

#include <iostream>int const MAX = 10;// eof+bad+good+fail+clear testint main(){

char line[MAX];for (;;){

cin.getline(line, MAX, '\n');if (cin.fail()) cout << " fail ";if (cin.bad()) cout << " bad ";if (cin.good()) cout << " good ";if (cin.eof()) break;if (!cin.good()) cin.clear();cout << line << endl;

}cout << "eof" << endl;return 0;

}

Page 45: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les manipulateurs

Un certain nombre de paramètres pour le format des sorties peuvent être explicitement spécifiés. Ces paramètres sont de deux formes:

➱ Soit des manipulateurs, appliqués à l’opérateur « << »➱ Soit des options de configurations, appliqués directement au stream de sortie

ManipulateursPour utiliser les manipulateurs, il faut au préalable importerles définitions du fichier iomanip au moyen de la directive d’inclusion:

#include <iomanip>

On utilise les manipulateurs très simplement, en les insérant directementdans le flot, à l’endroit désiré, exactement comme avec les données:

cout << «donnée» << «manipulateur» << «donnée» << ...

Page 46: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les sorties formatées

Longueur de la représentation: setw(«taille»)

La donnée qui suit ce manipulateur est affiché sur (au moins) taille caractères, avec (par défaut) un cadrage à droite, fort pratique lors de la représentation en colonnes des nombres.

cout << setw(10) << "un:"<< setw(5) << 1 << endl;cout << setw(10) << "cent deux:"<< setw(5) << 102 << endl;cout << setw(10) << "moins 18:"<< setw(5) << -18 << endl;

un: 1cent deux: 102 moins 18: -18

#include <iomanip>

Page 47: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les sorties formatées

Caractère de remplissage: setfill(«char»)

Il définit le caractère utilisé pour pour réaliser le remplissage lors d’un alignement (par défaut le caractère espace):

cout << setw(10) << "un:"<< setfill(’.’) << setw(5)<< 1;cout << endl << setw(10) << "cent deux:"<< setfill(’.’) << setw(5) << 102;cout << endl << setw(10) << "moins 18:"<< setfill(’.’) << setw(5) << -18

un:…1cent deux:..102 moins 18:..-18

#include <iomanip>

Page 48: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les sorties formatées

Précision en virgule flottante: setprecision(int)

Il définit le nombre de chiffres significatifs sur lequel se fera l’affichage des nombre en virgules flottantes (par défaut 6, partie entière + décimale):

for (int i(2); i<6; ++i){

cout << setprecision(i) << i<< ’ ’ << 314.1592654 << endl;

}

2 3.1e+0023 3144 314.25 314.16

#include <iomanip>

Page 49: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Les entrées/sorties

Comme avec les printf du C, il est donc possible de spécifier des formats d'affichage à la manière des fameux "%6.2f" dans le langage C.

L'exemple suivant créé l'équivalent d'un printf("6.2f",r);

#include <iostream> #include <iomanip> using namespace std;

int main(int, char **) {

double r=36.145278; int i=5; cout << setw(6) << setprecision(4) << r << endl; cout << i << " " << i++ << endl; cout << i << endl; return 0;

}

36.14

6 5

6

Les appels sont réalisés de la droite vers la gauche.

Les expressions que vous affichez sont présentées dans l'ordre que vous avez demandé mais elles ont été évaluées dans l'ordre inverse.

De plus, setprecision(4) sera active pour

les éventuelles impressions de réels.

Page 50: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers

• Fichier : séquence d’octets terminée par une « marque de fin de fichier » (EOF).

• En C++ : vus comme des flux d’octets ou de caractères.• ofstream : Pour l’écriture dans un fichier.• ifstream : Pour la lecture à partir d’un fichier.

• Deux types de lecture/écriture :• Mode texte : Peut être lu comme un document texte, caractère

par caractère, mot par mot, ligne par ligne, etc.• Mode binaire : décoder les informations, octet par octet.

• Se trouve dans l’entête <fstream>

Page 51: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers texte

Le lien entre les fichiers du système d’exploitation et le programme se fait en C++ par le biais des streams. Un flot de données de type stream – orienté ou bidirectionnel – peut être associé à un fichier, et s’utilise de la même manière que les flots vers ou en provenance de la console (cin, cout, cerr).

Page 52: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers texte

Pour pouvoir utiliser les streams liés aux fichiers, il faut importer, en début de programme, les prototypes et définitions contenus dans la librairie, au moyen de la directive d’inclusion:

#include <fstream>

Deux types (classes) sont alors disponibles:

➱ ifstream (input file stream) stream d’entrée associé à un fichier ouvert en mode lecture (similaire à cin)

➱ ofstream (output file stream) stream de sortie, associé à un fichier ouvert en mode écriture (similaire à cout).

Page 53: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers texte

Le mécanisme général pour la mise en oeuvre d’entrée-sorties via les fichiers est:

(1) Création d’un stream (d’entrée ou de sortie),par la déclaration d’une variable de type ifstream ou ofstream.

Exemple ifstream entree;ofstream sortie;

(2) Association de la variable avec un fichier physique, par l’appel de la fonction-méthode open, en respectant la syntaxe d’appel définie dans le paragraphe concernant les vecteurs.

Exemple entree.open("input.txt");

qui associe le stream entree avec le fichier nommé «input.txt» (présent dans le répertoire courant).

(3) Utilisation du stream: par des appels à des fonctions-méthodes, et l’utilisation des opérateurs d’insertion («>>») et d’extraction («<<») de données.

(4) Fermeture du stream, au moyen de la fonction-méthode closeExemple entree.close();

Page 54: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers texte

Les opérations (1) et (2), à savoir la déclaration de la variable et son association avec un fichier, peuvent se réaliser en une seule étape. L’initialisation lors de la déclaration se fait alors en spécifiant entre parenthèses le nom du fichier à lier au stream:

Exemple ifstream entree("input.txt");

On peut considérer que l’initialisation fait directement appel à la fonction open. La fonction open admet comme argument une chaîne de caractères de type "..." (en fait un char[]): il n’est donc pas possible d’utiliser directement une chaîne de type string (en effet, s’il y a conversion implicite des chaînes de la forme "..." vers les strings (promotion), l’inverse n’est pas

vrai.) . Il faut dans ce cas demander la conversion en type char[] du string, en faisant appel à la fonction-méthode c_str:

Exemple string str("output.txt");ifstream entree2;ofstream sortie(str.c_str());entree2.open(str.c_str());

Page 55: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers texte

ifstream de("fichier1"); // définition de la variable: deif (!de){

cerr<<"Impossible d'ouvrir fichier1 en lecture\n";exit(1);

}ofstream vers("fichier2"); // définition de la variable: versif (!vers){

cerr<<"Impossible d'ouvrir fichier2 en écriture\n";exit(1);

}char c;while(de.get(c)) //copie de fichier1 vers fichier2vers<<c;;

get(c) retourne faux si on est à la fin du fichier, sinon elle retourne vrai.

Exemple 2

Page 56: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers texte

L’utilisation dans le programme des variables de type fstream pour effectuer des entrées-sorties se fait de la même manière que pour les streams cin et cout, c’est-à-dire à l’aide des opérateurs d’insertion «>>» et d’extraction «<<».

ifstream entree("input.txt");ofstream sortie("output.txt");string mot; int n;entree >> mot >> n;sortie << "Le mot lu est: ’" << mot << "’ et le "<< "nombre est: ’" << n << "’." << endl;

Exemple

Remarque. Une fonction utile pour tester si le lecture d’un fichier est Terminée est la fonction/méthode eof.

if (entree.eof()) {cout << "Fin du fichier" << endl;}

Page 57: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers texte

Le programme ci-dessous saisit une phrase via l’entrée standard (clavier), et l’écrit (un mot par ligne) dans un fichier texte nommé «phrase.txt».

#include <iostream>#include <fstream>#include <string>int main(){

string motSaisit;string nomFichier("phrase.txt");ofstream sortie(nomFichier.c_str());cout << "Entrez une phrase terminée par « .»" << endl;do{

cin >> motSaisit;sortie << endl << motSaisit;

} while (motSaisit != ".");sortie.close();return 0;

}

Page 58: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers texte

Le programme ci-dessous relit le fichier créé par le programme précédant,et affiche la phrase à l’écran, et remettant les mots sur une même ligne.

#include <iostream>#include <fstream>#include <string>int main(){

string motSaisit;ifstream entree("phrase.txt");while (!entree.eof()){

entree >> motSaisit;cout << motSaisit << ’ ’;

}cout << endl;entree.close();return 0;

}

Page 59: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers texte

De même qu’il est conseillé de contrôler la conformité des valeurs entrées par un utilisateur, il est bon de vérifier que l’association d’un stream avec un fichier s’est correctement réalisée (i.e. que le fichier existe, est lisible, etc). Pour cela, on peut «évaluer le stream», après l’appel à la fonction open.Si tout c’est bien passé, le résultat de cette évaluation sera true,et il sera false en cas de problème.

Exemple

entree.open("fichier-inexistant");if (!entree) cout << "Oops, le fichier n’est pas lisible!" << endl;else << cout << "Ok, le fichier existe et est lisible!" << endl;

Plus précisément, un certain nombre de prédicats, déjà rencontrés, sont associés aux streams, et permettent d’en connaître l’état:

bool good() le stream est dans un état correct, la prochaine opération (lecture/écriture) sera un succès.

bool eof() la fin du stream à été atteinte.bool fail() la prochaine opération (lecture/écriture) échouera.

Elle sert lors de l’«évaluation» d’un stream.bool bad() le stream est corrompu: des données ont été perdues

(et la prochaine opération échouera).

Page 60: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers texte

Retour sur les fonctions open() et close()

Ouverture d’un fichier avec un mode explicite

Modes C++ Signification ios::in read ios::write write ios::app append

ios::binary binaire

flot.open("toto1", ios::out); f= fopen("toto1", "w");flot.open("toto2", ios::in); f= fopen("toto2", "r");

En C

Page 61: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers texte

Les fonctions open() et close()

Un fichier est automatiquement ouvert à la création d ‘une variable si on utilise la syntaxe suivante:

ofstream ofs ("toto.out", ios::out); ifstream ifs ("toto.in", ios::in);

Déclarer un objet de type ofstream (fichier en sortie) ou ifstream (fichier en entrée):

• 1er argument : le chemin et le nom du fichier.• 2e argument : le type d’ouverture

• ios::out : Efface tout le contenu, si le fichier existait déjà.• ios::app : Écrit après ce qu’il y a déjà dans le fichier.• Si le fichier n’existe pas, il est créé dans les deux cas.

• Le fichier doit exister dans le cas d’un fichier en entrée

Page 62: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers texte

Les fonctions open() et close()

flot.fclose();

C++ est « dynamique»: lorsqu‘une variable de flot n ‘existe plus, le fichier éventuellement attaché au flot est automatiquement fermé.

Page 63: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers texte

Exemple 1

//Ouverture d'un fichier en écritureofstream ofs ("Moto.dat",ios::out);

if (!ofs){ cerr << "Ouverture impossible" <<endl; return 1;}ofs << 2 << endl; // nombre de motos

ofs << "Honda Shadow" << endl;ofs << 1986 <<endl;ofs << "Honda Valkyrie Rune" << endl;ofs << 2004 << endl;

// Pour forcer la fermetureofs.close();

Si le fichier ne peut être ouvert ( mauvais

chemin ou déjà ouvert ), l’opérateur !

Renvoie faux.

Pourra être relue comme une ligne entière

2Honda Shadow1986Honda Valkyrie Rune2004

2Honda Shadow1986Honda Valkyrie Rune2004

Page 64: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Entrée/sortie avec des fichiers texte

Exemple 2

{//Ouverture d'un fichier en écriture ifstream ifs("Moto.dat",ios::in); if(!ifs) { cerr << "Ouverture impossible" <<endl; return 1; } char ligne[256]; int nbMotos; ifs >> nbMotos; ifs.ignore(100, '\n'); for (int i=0; i<nbMotos; i++) { ifs.getline(ligne,255); cout << " Modele : " << ligne << endl; ifs >> annee; cout << " Annee : " << annee << endl << endl; ifs.ignore(100, '\n'); } } // destructeur de ifs appelé, qui ferme le fichier

Modèle : Honda ShadowAnnee : 1986

Modèle : Honda Valkyrie RuneAnnee :2004

Modèle : Honda ShadowAnnee : 1986

Modèle : Honda Valkyrie RuneAnnee :2004

Page 65: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Strings et streams

Il peut parfois être utile, en vue d’effectuer des traitements particuliers, de disposer d’une représentation sous forme de chaîne decaractères des différentes variables d’un programme.

Une telle convertion de représentation est automatiquement réaliséelorsque l’on insère ces éléments dans un stream de sortie, tel que cout.

Mais peut-on récupérer ce qui est transmis dans le flot ?

À défaut de récupérer ce qui est effectivement transmis, on peut du moins en obtenir l’équivalent sous forme de string, en utilisant des strings hybrides, associés à des streams. Ces entités hybrides sont désignées « stringstream».

Pour pouvoir utiliser les stringstream dans un programme, il faut importer les prototypes et définitions contenus dans la librairie, au moyen de la directive d’inclusion:

#include <sstream>

Page 66: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Stringstream de sortie

Pour obtenir la représentation alphanumérique d’une variable,il faut utiliser un stringstream de sortie, dans lequel on insérera lesdonnées désirées (de la même manière qu’avec cout) avant d’enextraire l’équivalent sous forme de chaîne de caractère.

Le type (la classe) matérialisant de tels éléments est désigné: ostringstream, et l’extraction de la représentation chaîne s’obtient au moyen de la méthode: string str().

#include <sstream>...string composeMessage(const int errno, const string& description){

ostringstream ost;ost << "Erreur (n°" << errno << "): " << description;return ost.str();

}

Exemple

Page 67: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Stringstream d’entréeIl est également possible de réaliser des entrées depuis un string (au lieu du clavier, avec cin): il suffit d’initialiser un stringstream d’entrée avec la chaîne désirée, et d’utiliser l’opérateur d’extraction sur le stream ainsi obtenu. Le type (la classe) utilisé est: istringstream.

#include <sstream>...// Extrait les mots d’un string, et les affiches à// raison de un par lignevoid wordByWord(const string& str){

istringstream ist(str);string s;while (ist >> s) {cout << s << endl;}

}// en utilisant la fonction précédante:wordByWord("Erreur (no5): Fichier non trouvé.");}

Exemple

Erreur (n˚5): Fichier non trouvé.

Page 68: Structures de données IFT-2000 Abder Alikacem Les entrées/sorties en C++ Département dinformatique et de génie logiciel Édition Septembre 2009

Hiérarchie des classes représentant les flots