Chapitre 4 Entrées - Sorties
Chapitre 4 Entrées - Sorties
Chapitre 4 Entrées - Sorties
ENTREES/ SORTIES
1
CLASSES DE GESTION DES FLUX
Les entrées et sorties sont gérées par deux classes définies dans le fichier d'en-tête <iostream> :
• iostream (Output stream) permet d'écrire des données vers la console, un fichier, ... Cette
classe surdéfinit l'opérateur <<.
• istream (Input stream) permet de lire des données à partir de la console, d'un fichier, ...
Cette classe surdéfinit l'opérateur >>.
FLUX STANDARDS
EXEMPLE
#include <iostream>
int main()
{
int n;
cout << "Entrez un nombre positif : ";
cin >> n;
if (n<0) cerr << "Erreur: Le nombre " << n
<< " n'est pas positif " << endl;
else cout << "Vous avez entré " << n << endl;
return 0;
}
AUTRES TYPES DE FLUX
Les instances des classes dérivées des classes istream et ostream sont également manipulés avec
les opérateurs << et >>. Cependant, il ne faut pas oublier de les fermer en appelant la méthode
close().
Note: Les noms de fichiers sont codés sur 8 bits sous Linux/Unix et sur 16 bits sur Windows,
ce qui peut induire des problématiques de portabilité, le cas échéant.
FLUX DE FICHIER
La classe ifstream permet de lire à partir d'un fichier. Le constructeur a la syntaxe suivante :
2
Le paramètre mode peut être une combinaison des valeurs suivantes :
app
(append) Placer le curseur à la fin du fichier avant écriture.
ate
(at end) Placer le curseur à la fin du fichier.
binary
Ouvrir en mode binaire plutôt que texte.
in
Autoriser la lecture.
out
Autoriser l'écriture.
trunc
(truncate) Tronquer le fichier à une taille nulle.
ifstream fichier("test.txt");
int a;
fichier >> a; // lire un entier
cout << "A = " << a;
fichier.close();
ifstream fichier("test.txt");
while (fichier.good())
cout << (char) fichier.get();
fichier.close();
La classe ofstream permet d'écrire vers un fichier. Son constructeur a une syntaxe similaire :
Exemple :
ofstream fichier("test.txt");
fichier << setw(10) << a << endl;
fichier.close();
3
La classe fstream dérive de la classe iostream permettant à la fois la lecture et l'écriture. Cette
dernière (iostream) dérive donc à la fois de la classe ostream et de la classe istream. Son constructeur
a la syntaxe suivante :
Exemple :
fstream fichier("test.txt");
fichier << setw(10) << a << endl;
fichier.seekg(0, ios_base::beg);
fichier >> b;
fichier.close();
FLUX DE CHAINE DE CARACTERES
Ces flux permettent d'écrire pour produire une chaîne de caractères, ou de lire à partir d'une
chaîne de caractères.
La classe istringstream dérivée de istream permet de lire à partir d'une chaîne de caractères, et
possède deux constructeurs :
Exemple :
int n, val;
string stringvalues;
stringvalues = "125 320 512 750 333";
istringstream iss (stringvalues, istringstream::in);
La classe ostringstream dérivée de ostream permet d'écrire pour créer une chaîne de caractères, et
possède également deux constructeurs :
Exemple :
La classe stringstream dérivée de iostream permet d'écrire et lire, et possède deux constructeurs :
Exemple :
int n, val;
stringstream ss (stringstream::in | stringstream::out);
// écriture
ss << "120 42 377 6 5 2000";
// lecture
for (int n = 0; n < 6; n++)
{
ss >> val;
cout << val << endl;
}
MANIPULATEURS
Le fichier d'en-tête <iomanip> définit des manipulateurs de flux tels que endl, hex. Ces
manipulateurs modifient la façon d'écrire ou lire les données qui suivent celui-ci.
MANIPULATEUR ENDL
Ce manipulateur écrit un retour à la ligne dans le flux, quel qu'il soit (\r\n pour Windows, \n pour
Unix/Linux, \r pour Mac, ...). Il est donc conseillé de l'utiliser au lieu du/des caractère(s)
correspondant(s), si la portabilité de votre application joue un rôle important.
Exemple:
cout << "Une première ligne" << endl << "Une deuxième ligne" << endl;
N.B.: Certains compilateurs C++ (notamment Visual C++) ne supporte pas que le manipulateur
endl soit suivi d'autres données à écrire. Dans ce cas, il faut écrire les données suivantes dans
une nouvelle instruction :
Ce manipulateur indique que les prochains entiers sont à lire ou écrire en base hexadécimale.
5
MANIPULATEUR DEC
Ce manipulateur indique que les prochains entiers sont à lire ou écrire en base décimale.
MANIPULATEUR SETBASE(BASE)
Les 2 manipulateurs précédents sont des alias de celui-ci, qui permet de spécifier la base des
prochains entiers à lire ou écrire.
Exemple :
cout << "Valeur de a en base 16 = " << setbase(16) << a << endl;
// affiche: Valeur de a en base 16 = C8
cout << "Valeur de a en base 10 = " << setbase(10) << a << endl;
// affiche: Valeur de a en base 10 = 200
cout << "Valeur de a en base 8 = " << setbase(8) << a << endl;
// affiche: Valeur de a en base 8 = 310
MANIPULATEUR SETW(WIDTH)
Ce manipulateur indique que les prochaines données doivent être écrites sur le nombre de
caractères indiqué, en ajoutant des caractères espaces avant.
Exemple :
int a = 11;
cout << "Valeur de a = " << setw(5) << a << endl;
Ce code affiche :
Valeur de a = 11
MANIPULATEUR SETFILL(CHAR)
Exemple :
int a = 11;
cout << "Valeur de a = " << setfill('x') << setw(5) << a << endl;
Ce code affiche :
Valeur de a = xxx11
6
MANIPULATEUR SETPRECISION(DIGITS)
Ce manipulateur spécifie que les prochains nombres à virgule flottante doivent être écrits avec
la précision donnée. La précision donne le nombre maximum de chiffres à écrire (avant et après
la virgule).
Exemple :
double f = 3.14159;
cout << setprecision (5) << f << endl;
cout << setprecision (9) << f << endl;
Ce code affiche :
3.1416
3.14159
MANIPULATEURS SETIOSFLAGS ET RESETIOSFLAGS
Le manipulateur setiosflags (resp. resetiosflags) active (resp. désactive) des options de format des
données.
Ces deux manipulateurs possèdent un argument dont le type est défini par l'énumération
ios_base::fmtflags. Cet argument peut être :
ios_base::boolalpha
Ecrire/lire les données de type bool sous forme textuelle, càd true ou false.
ios_base::oct
Ecrire/lire les entiers en base octale (base 8).
ios_base::dec
Ecrire/lire les entiers en base décimale (base 10).
ios_base::hex
Ecrire/lire les entiers en base hexadécimale (base 16).
ios_base::showbase
Faire précéder les entiers par leur base.
ios_base::showpos
Faire précéder les nombres positifs du signe plus ( + ).
ios_base::showpoint
Toujours écrire la virgule des nombres réels.
ios_base::fixed
7
Ecrire les nombres réels avec une virgule fixe.
ios_base::scientific
Ecrire les nombres réels sous forme scientifique.
ios_base::left
Aligner les donnés à gauche (setw).
ios_base::right
Aligner les donnés à droite (setw).
ios_base::internal
Aligner les donnés en remplissant à une position interne (setw).
ios_base::skipws
Ignorer les caractères blancs avant de lire les données.
ios_base::unitbuf
Vider le buffer de sortie à chaque écriture.
ios_base::uppercase
Ecrire les données en majuscules.
Il en va de même pour les objets. Un objet déclaré const ne pourra pas être modifié, c'est-à-dire
que le compilateur refusera l'invocation d'une méthode non const sur cet objet.
Exemple :
class X {
public:
X() : valeur_(0) {}
explicit X(int valeur) : valeur_(valeur) {}
void annule() { this->valeur_ = 0; }
void init(int valeur) { this->valeur_ = valeur; }
int valeur() const { return this->valeur_; }
private:
int valeur_;
};
X x(2)
const X y(5);
x.annule(); // Ok
y.annule(); // Erreur de compilation.
8
Dans cet exemple, deux objets x et y ont été déclarés. Il est possible d'invoquer n'importe quelle
méthode (const ou non) sur l'objet x, par contre seules les méthodes const peuvent être
invoquées sur l'objet y puisqu'il est déclaré const.
L'OPERATEUR SIZEOF
L'opérateur sizeof permet de savoir le nombre d'octets qu'occupe en RAM une certaine variable.
On peut écrire sizeof(a) pour savoir le nombre d'octets occupé par la variable a. On peut aussi
écrire, sizeof(int) pour connaître le nombre d'octets occupés par une variable de type int. Cet
opérateur est très utile lorsqu'on veut résoudre des problèmes de portabilité d'un programme.
Plus précisément sizeof(char) vaut toujours 1, par définition. Sur la plupart des architectures un
char est codé par huit bits, soit un octet. Programmation C/Types de base#Caractères
L'instruction typedef permet de définir un alias pour un type de données. Ceci permet dans
certains cas de raccourcir le code, et dans tous les cas c'est l'occasion de donner un nom plus
explicite à un type. Ceci favorise une meilleur lecture du code.
La syntaxe de typedef est exactement la même que celle de la déclaration d'une variable, excepté
que l'instruction commence par typedef et qu'aucune variable n'est réservée en mémoire, mais
un alias du type est créé.
Exemple:
On s'aperçoit plus facilement que la fonction retourne le nombre d'octets lus que dans la
déclaration sans typedef :
Références bibliographiques
9
10