Gestion des entrées-sorties & fichiers
Les flux standards (cin, cout, cerr), surcharger << et >> avec gestion d'erreurs, lire et écrire dans un fichier avec <fstream>.
📄 Ressources du cours
🎥 Vidéos recommandées
-
🇫🇷
How To Use ifstream To Read Files | C++ Tutorial
Portfolio Courses · 12:31 · 12k vues — How to use ifstream objects to read the contents of files in C++. Source code: https://github.com/portfoliocourses/cplusplus-example-code/blob/main/ifstream...
-
🇫🇷
31- C++ Course Level 2 (Fstream , IFstream and OFstream)
محمد شوشان · 07:01 · 12k vues — الدرس رقم 31 من كورس السي بلس بلس المستوي الثاني البرمجه الكائنيه وفي هذا الدرس نقوم بشرح كامل لتالي:شرح تفصيلي ل Fstreamشرح تفصيلي ل IFstreamشرح تفصيلي ل OF...
-
🇬🇧
Reading from a File using ifstream class | C++ Video Tutorial
LearningLad · 06:09 · 56k vues — In this c++ Video tutorial,, you will learn how to read from a file using an if stream class object. You are gonna learn how to create an object of ifstream ...
1. Architecture — tout est flux
Trois flux standards sont déjà ouverts au démarrage du programme :
| Flux | Sens | Périphérique par défaut |
|---|---|---|
cout | sortie | écran (console) |
cin | entrée | clavier |
cerr | sortie d'erreur | écran (console) |
Et deux opérateurs pour interagir avec eux :
<<— écrit sur un flux de sortie (« insertion »)>>— lit depuis un flux d'entrée (« extraction »)
int age;
cout << "Ton âge ? ";
cin >> age;
cout << "Tu as " << age << " ans" << endl;
cerr << "erreur diagnostique sur stderr" << endl;
En C on utilisait
FILE* stdin, stdout, stderr; avec printf, scanf, fopen, fclose. En C++ on remplace tout par les flux objets typés et les opérateurs << / >>.
2. Surcharger << et >> pour ses propres classes
Les types fondamentaux savent déjà se sérialiser. Pour ses propres classes, il faut surcharger les opérateurs (cf. CM3). Toujours en fonction non-membre, souvent friend pour accéder aux privés.
// fraction.h
class Fraction {
private:
int numerateur = 0;
int denominateur = 1;
public:
friend ostream& operator<<(ostream& out, const Fraction& f);
friend istream& operator>>(istream& in, Fraction& f);
};
Sortie — <<
ostream& operator<<(ostream& out, const Fraction& f) {
out << f.numerateur << "/" << f.denominateur;
return out; // chaînage
}
Fraction f(5, 6);
cout << f; // affiche "5/6"
Entrée — >> avec gestion d'erreur
Pour lire une fraction au format n/d, on doit lire trois choses dans l'ordre : un entier, le caractère /, un autre entier. Si le format est invalide, on marque le flux comme défaillant via setstate(ios::failbit).
istream& operator>>(istream& in, Fraction& f) {
char c;
if (!(in >> f.numerateur >> c >> f.denominateur) || c != '/') {
in.setstate(ios::failbit);
}
return in;
}
Fraction f;
cout << "Entrez une fraction : ";
cin >> f; // l'utilisateur tape "5/6"
failbit — drapeau d'erreur logique
Si la lecture échoue (mauvais format, EOF prématuré…), on positionne le bit failbit. C'est ensuite à l'appelant de tester avec fail() ou !flux pour gérer l'erreur.
3. Fichiers — physique vs logique
- Fichier physique : collection d'octets stockée sur un support (disque, SSD).
- Fichier logique : variable du programme (un flux) liée au fichier physique pendant la session.
L'en-tête à inclure pour les flux fichiers :
// fournit les trois classes ci-dessous
#include <fstream>
| Classe | Rôle |
|---|---|
ofstream | écrire dans un fichier (output) |
ifstream | lire depuis un fichier (input) |
fstream | lire ET écrire |
ofstream hérite d'ostream, ifstream d'istream. C'est pour ça que les opérateurs << / >> surchargés pour cout / cin fonctionnent tels quels sur les fichiers.
4. Ouvrir et fermer un fichier
Constructeurs
#include <fstream>
// lecture
ifstream ifs("chemin/vers/fichier.txt");
// écriture
ofstream ofs("chemin/vers/fichier.txt");
// écriture avec mode
ofstream ofs2("data.txt", ios::app); // append — ajout en fin de fichier
Modes d'ouverture
| Mode | Effet |
|---|---|
ios::in | lecture (défaut pour ifstream) |
ios::out | écriture (défaut pour ofstream) |
ios::app | ajoute à la fin du fichier (append) |
ios::ate | positionne le curseur à la fin à l'ouverture (at end) |
ios::trunc | vide le fichier à l'ouverture (truncate) |
ios::binary | ouvre en mode binaire (pas texte) |
On peut combiner les modes avec l'opérateur bit-à-bit | :
ofstream ofs("data.txt", ios::in | ios::app);
Fermeture
ofs.close(); // libère le verrou et flushe le buffer
ofstream / ifstream appelle close() automatiquement quand l'objet sort du scope. C'est l'idiome RAII (resource acquisition is initialization) — la même garantie que pour new/delete en CM2.
5. Écrire dans un fichier
Même syntaxe que cout — << sur le flux logique. Toute valeur de type simple (bool, int, double, string…) ou toute classe ayant un operator<< surchargé peut être écrite.
#include <fstream>
Fraction f1(1, 2);
Fraction f2(2, 3);
ofstream ofs("Fractions.txt", ios::out);
ofs << f1 << endl;
ofs << f2 << endl;
ofs.close();
// résultat — contenu de Fractions.txt :
// 1/2
// 2/3
6. Lire un fichier
Lecture mot par mot — >>
L'opérateur >> lit jusqu'au premier espace blanc (espace, tabulation, retour à la ligne) ou jusqu'au premier caractère qui ne fait pas partie du type lu.
ifstream ifs("Fractions.txt");
Fraction f;
ifs >> f;
cout << "Lu : " << f << endl;
ifs.close();
Lecture ligne par ligne — getline()
bool getline(ifstream& in, string& line); // signature simplifiée
- renvoie
truetant qu'il reste des données - renvoie
falseà la fin du fichier
ifstream ifs("texte.txt");
string ligne;
while (getline(ifs, ligne)) {
cout << ligne << endl;
}
ifs.close();
7. Vérifier l'état d'un flux
Avant ou pendant les opérations, on teste l'état pour détecter les erreurs :
Exemple — lire fichier en vérifiant erreurs
ifstream ifs("Fractions.txt");
if (ifs) { // teste l'ouverture (good())
Fraction f;
while (!ifs.eof()) {
ifs >> f;
if (!ifs.fail()) {
cout << f << endl;
}
}
ifs.close();
}
else {
cerr << "Impossible d'ouvrir le fichier" << endl;
}
if (ifs) { ... } exploite la conversion implicite d'un fstream en bool : true si le flux est sain (équivalent à !fail()), false sinon. Plus idiomatique que if (ifs.good()).
8. Position dans le fichier
- g comme get (lecture,
ifstream) - p comme put (écriture,
ofstream)
| Méthode | Effet |
|---|---|
tellg() | position courante en lecture |
tellp() | position courante en écriture |
seekg(pos, mode) | se positionne en lecture |
seekp(pos, mode) | se positionne en écriture |
Le paramètre mode de seekg / seekp :
ios::beg— depuis le début du fichierios::cur— depuis la position couranteios::end— depuis la fin du fichier
ifs.seekg(0, ios::beg); // retour au début
ifs.seekg(10, ios::cur); // avance de 10 octets
ifs.seekg(-5, ios::end); // 5 octets avant la fin
9. Exemple complet — répertoire téléphonique
Programme 1 — saisir et sauvegarder
#include <fstream>
#include <iostream>
void main() {
string nom, tel;
ofstream fichrep("repertoire.txt"); // ouverture écriture
for (int i = 0; i < 10; i++) {
cout << "\npersonne " << i+1 << ":\n";
cout << "nom ? "; cin >> nom;
fichrep << nom << " ";
cout << "\ntéléphone ? "; cin >> tel;
fichrep << tel << "\n";
}
fichrep.close();
}
Programme 2 — relire et afficher
#include <fstream>
#include <iostream>
void main() {
string nom, tel;
ifstream fichrep("repertoire.txt"); // ouverture lecture
fichrep >> nom >> tel;
while (!fichrep.eof()) {
cout << nom << "\t" << tel << "\n";
fichrep >> nom >> tel;
}
fichrep.close();
}
On lit une première ligne avant la boucle, puis dans la boucle on affiche puis on re-lit. Ainsi
eof() est testée juste après chaque tentative de lecture. Sinon, la dernière itération afficherait des données fantômes (la lecture aurait échoué).
★ Réviser le chapitre
Pour vérifier ta compréhension
Quelle est la différence entre ifstream, ofstream et fstream ?
ifstream = input file stream (lecture seule). ofstream = output file stream (écriture seule). fstream = bidirectionnel (lecture et écriture, à préciser avec ios::in | ios::out).
Comment vérifier qu'un fichier s'est bien ouvert ?
Tester directement le flux : if (!fichier) { /* erreur */ } ou if (!fichier.is_open()) { … }. Toute opération sur un flux fermé/échoué est silencieusement ignorée — il faut toujours vérifier l'ouverture.
Quelle est la différence entre >> et getline() ?
>> lit jusqu'au prochain espace blanc (espace, tab, saut de ligne). getline() lit jusqu'au prochain séparateur (saut de ligne par défaut), espaces inclus. Pour lire une phrase complète, utiliser getline(fichier, ligne);.
Comment fermer un fichier en C++ ?
Soit explicitement : fichier.close();, soit implicitement via le destructeur du flux quand l'objet sort de portée (RAII). C'est généralement plus sûr de laisser le destructeur s'en occuper sauf si on veut libérer la ressource plus tôt.
À quoi servent les manipulateurs de format comme std::setw ou std::fixed ?
Ils configurent le formatage du flux : std::setw(10) impose une largeur de 10 caractères, std::fixed + std::setprecision(2) affiche les flottants en virgule fixe à 2 décimales, std::left/std::right aligne. Inclus dans <iomanip>.
🃏 Flashcards
cout (sortie écran), cin (entrée clavier), cerr (sortie d'erreur écran). Tous trois définis dans <iostream>.<< = écrire (insertion) sur un flux de sortie. >> = lire (extraction) sur un flux d'entrée. Le double chevron pointe dans la direction du flux.operator<< pour une classe T ?ostream& operator<<(ostream& out, const T& obj). Non-membre, souvent friend, retourne out par référence pour le chaînage.operator>> ?in.setstate(ios::failbit). Le test ultérieur fail() renverra true, signalant l'erreur sans interrompre le programme.#include <fstream>. Il fournit les classes ifstream, ofstream, fstream (lecture, écriture, bidirectionnel).ios::app ?ios::app, l'ouverture en écriture vide le fichier par défaut.ios::trunc ?ios::out sans autre mode.bad() et fail() ?bad() = erreur physique (écrire sur un flux en lecture, disque plein…). fail() = erreur physique ou erreur de format. fail() est plus large.getline(ifs, ligne) ?\n) du flux dans la chaîne. Renvoie true tant qu'il reste des données, false à la fin.>> s'arrête-t-il lors d'une lecture ?close() explicitement ?fstream appelle close() à la fin du scope (RAII). Mais c'est plus explicite quand on veut flusher le buffer ou réutiliser le fichier ailleurs avant la fin du scope.tellg() et tellp() ?g = get (lecture), p = put (écriture).seekg(pos, mode) ?ios::beg (depuis le début), ios::cur (depuis la position courante), ios::end (depuis la fin).✎ Quiz éclair
ifstream ?<fstream> fournit ifstream, ofstream et fstream. <iostream> ne suffit pas pour les fichiers.ios::app (append) garantit que les écritures s'ajoutent en fin de fichier. "a" est la syntaxe du C, pas du C++.cin >> str où str est un string, jusqu'où la lecture va-t-elle ?>> sur un string s'arrête au premier espace. Pour lire toute une ligne y compris les espaces, utiliser getline().getline(ifs, ligne) quand on atteint la fin du fichier ?getline renvoie true tant qu'il reste des données, false à la fin. C'est pour ça qu'on l'utilise typiquement comme condition de boucle while.operator>> de Fraction, pourquoi in.setstate(ios::failbit) ?failbit marque le flux comme défaillant. L'appelant peut alors tester fail() pour décider de la suite. Approche non-intrusive.if (ifs) { ... } teste :fstream a une conversion implicite en bool qui renvoie true tant que le flux est sain.seekg (g pour get). Le mode ios::end compte depuis la fin ; un offset négatif remonte vers le début.close() sur un ofstream local :ofstream appelle close(). close() manuel reste utile pour libérer plus tôt ou flusher explicitement.Score : 0 / 8 ·
