Annexe A Format des entrées-sorties
Ce chapitre, dû à Philippe Dosch [1] que je remercie une
fois de plus, donne quelques précisions supplémentaires sur les
entrées-sorties en C++.
A.1 La classe ios
La classe ios est la classe de base des classes représentant
les flots.
Toutes les classes de flot présentées ci-dessous héritent donc de
cette classe et des méthodes qu'elle définit (non exhaustif) :
-
int ios::good()
: retourne une valeur nulle s'il y a eu un
échec lors de la dernière opération d'entrée-sortie, et une valeur
non nulle sinon.
-
int ios::fail()
: retourne le contraire de la méthode
précédente.
-
int ios::eof()
: retourne une valeur non nulle si la fin de
fichier est atteinte, et la valeur nulle sinon.
La classe ios définit aussi un certain nombre de méthodes
relatives au format des informations manipulées (non exhaustif).
Voici un exemple d'utilisation :
#include <iostream>
int main()
{
cout << "Largeur standard : "
<< cout.width() << endl; // Affiche : 0
cout.width(10);
cout.fill('#');
cout << 654 << endl; // Affiche : #######654
}
-
int ios::width(int n)
: positionne la largeur du champ (le
nombre de caractères) de sortie.
-
int ios::width()
: retourne la largeur du champ de sortie.
-
char ios::fill(char c)
: positionne le caractère de remplissage
(utilisé pour remplir toute la largeur des champs).
-
char ios::fill()
: retourne le caractère de remplissage.
-
int ios::precision(int p)
: positionne la précision,
c'est-à-dire le nombre de caractères (y compris le point) qu'occupe
un réel.
-
int ios::precision()
: retourne la précision.
Enfin, cette classe définit un certain nombre d'opérations qui peuvent
être utilisées sans les préfixer du flot sur lequel on travaille, et
autorise ainsi l'écriture de lignes du type :
cout << "La valeur octale de 154 est : " << oct << 154
<< endl;
Parmi ces opérations, on trouve :
-
endl : écrit un '\n' et vide le
tampon du flot.
-
ends : écrit un '\0' et vide le
tampon du flot.
-
flush : vide le tampon du flot.
-
dec : la prochaine opération d'entrée-sortie se fera en
décimal.
-
hex : la prochaine opération d'entrée-sortie se fera en
hexadécimal.
-
oct : la prochaine opération d'entrée-sortie se fera en
octal.
-
ws : saute les espaces lors d'une lecture sur un flot
d'entrée.
-
setfill(int c) : positionne le caractère de remplissage
pour la prochaine opération d'entrée-sortie.
-
setprecision(int p) : positionne la précision de la
prochaine opération d'entrée-sortie à p chiffres.
-
setw(int n) : positionne la largeur de la prochaine
entrée-sortie à n caractères.
A.2 La classe ostream
Cette classe est dédiée aux sorties formatées ou non.
Un objet de type ostream est défini par défaut dans tout
programme C++ : c'est la variable cout.
La classe ostream surcharge l'opérateur << pour
tous les types prédéfinis du C++.
Il faut, si besoin est, le surcharger pour les nouveaux types
introduits (cf. § 3.9).
En plus de l'opérateur <<, la classe ostream est
dotée des méthodes suivantes (non exhaustif) :
-
ostream &ostream
::
put(char c) : insère un caractère dans le
flot.
Exemple : cout.put('n').
-
ostream &ostream
::
write(const char* s, int n) : insère
n caractères dans le flot.
-
ostream &ostream
::
flush() : vide le tampon du flot.
A.3 La classe istream
Cette classe est dédiée aux entrées formatées ou non.
Un objet de type istream est défini par défaut dans tout
programme C++ : c'est la variable cin.
La classe istream surcharge l'opérateur
>> pour tous les types prédéfinis du C++.
Il faut, si besoin est, le surcharger pour les nouveaux types
introduits (cf. § 3.9).
En plus de l'opérateur >>, la classe istream est
dotée des méthodes suivantes (non exhaustif) :
-
int istream::get()
: retourne la valeur du caractère lu
(EOF si la fin du flot est atteinte).
-
istream &istream::get(char &c)
: extrait le premier
caractère du flot (même si c'est un espace) et le place dans
c.
-
int &istream::peek()
: lit le prochain caractère du flot
sans l'enlever du flot (renvoie EOF si la fin du flot est
atteinte).
-
istream &istream
::
get(char* ch, int n, char delim =
'n') : extrait (n - 1) caractères du flot et
les place à l'adresse ch (le tampon).
La lecture s'arrête éventuellement après le délimiteur s'il est
rencontré.
-
istream &istream
::
getline(char* ch, int n, char delim =
'n') : identique à la méthode précédente sans placer
le délimiteur dans le tampon.
-
istream &istream
::
read(char* ch, int n) : extrait au plus
n caractères du flot et les place à l'adresse ch.
Le nombre de caractères effectivement lus peut être obtenu grâce à
la méthode gcount.
-
int istream::gcount()
: retourne le nombre de caractères
extraits lors de la dernière lecture.
-
istream &istream::flush()
: vide le tampon du flot.
A.4 Les fichiers
Les entrées-sorties sur les fichiers sont également réalisées avec des
flots en C++.
Ce type d'opérations nécessite l'inclusion de l'en-tête
fstream en plus de l'en-tête iostream.
Les deux grandes classes permettant de réaliser ces opérations sont :
-
La classe ofstream : cette classe est dédiée aux écritures
réalisées dans des fichiers.
La classe ofstream est dérivée de la classe
ostream et bénéficie donc de toutes les méthodes définies
dans cette classe.
Voici un exemple d'utilisation :
#include <iostream>
#include <fstream>
int main()
{
// Deux modes d'ouverture sont possibles :
// - ios::out -> création, fichier écrasé si existant
// - ios::app -> ajout en fin de fichier
ofstream fichierSortie("donnees.txt", ios::out);
// Test d'ouverture du fichier
if (!fichierSortie) {
cerr << "Problème d'ouverture de fichier" << endl;
exit(1);
}
fichierSortie << "J'écris des caractères dans le fichier "
<< "et des nombres : " << 10 << " " << 20
<< endl;
// Fermeture du fichier
fichierSortie.close();
}
-
La classe ifstream : cette classe est dédiée aux lectures
réalisées dans des fichiers.
La classe ifstream est dérivée de la classe
istream et bénéficie donc de toutes le méthodes définies
dans cette classe.
Voici un exemple d'utilisation :
#include <iostream>
#include <fstream>
int main()
{
// Ouverture du fichier
ifstream fichierEntree("donnees.txt", ios::in);
// Test d'ouverture du fichier
if (!fichierEntree) {
cerr << "Problème d'ouverture de fichier" << endl;
exit(1);
}
char buf[1024];
// Tant qu'il a y des lignes dans le fichier, on les
// lit et on les affiche à l'écran
while (!fichierEntree.eof()) {
fichierEntree.getline(buf, 1024);
cout << buf << endl;
}
// Fermeture du fichier
fichierEntree.close();
}