Afin d'ouvrir des fichiers, que ce soit en lecture ou en écriture, il faut utiliser la classe
ifstream (
Input
File
stream 
) pour la lecture et
ofstream (
Output
File
stream) pour l'écriture. Ces deux classes sont des dérivées de
std::ios_base qui, comme son nom l'indique, est la classe de base pour les flux.
Pour pouvoir les utiliser, il faut inclure l'entête fstream.
Le début du code est donc :
Code : C++1
2
3 | #include <fstream>
using namespace std;
|
Ouverture en lecture : ifstream
Maintenant, il faut ouvrir le fichier.
Pour ce faire, il faut un flux agissant sur le fichier.
Pour chaque fichier, il faut un flux différent !
Pour créer un flux, il nous faut un constructeur d'initialisation. Pour la lecture, il est de la forme
ifstream flux;. Une fois le flux créé, il faut ouvrir le fichier.
Pour l'ouvrir, on a deux possibilités :
- on utilise la fonction membre open qui prend deux paramètres : le premier est le nom du fichier à ouvrir, et le deuxième est le mode d'ouverture. Ça ressemble donc à flux.open("fichier.extension", mode_Ouverture); ;
- on ne passe pas par la fonction membre open, on indique directement le fichier et le mode d'ouverture en même temps que la déclaration du constructeur d'initialisation. Ça ressemble donc à ifstream flux("fichier.extension", mode_Ouverture);.
Dans la suite du tuto, je n'utiliserai pas la fonction open.
Pour indiquer l'emplacement du fichier, on a plusieurs solutions :
- le chemin absolu (= chemin complet, qui part de la racine du disque) qui est de la forme :
"C:/Documents and Settings/login/Bureau/fichier.txt" ;
- le chemin relatif (à partir de là où se trouve l'exécutable). Par exemple,
"sousDossier/fichier.txt" si le fichier se trouve dans un sous-dossier du dossier de l'exécutable ;
- si le fichier est dans le même répertoire que l'exécutable, il y a juste à indiquer le nom du fichier.
Moi, je suis sous Linux, je fais comment ?
Sous Linux, c'est : "/home/login/fichier.txt" qui est le chemin absolu. Le fonctionnement du chemin relatif est le même que pour Windows.
Les modes d'ouverture proviennent tous de la classe
ios_base, ce qui explique que l'on fasse précéder leur nom du préfixe
ios_base:: ou
ios:: tout court. Comme on veut ouvrir en lecture, c'est
ios::in (pour
input).
Une fois le fichier ouvert, il faut vérifier que l'ouverture a bien fonctionné. Pour cela, il suffit de faire
if(flux).
Une fois les opérations sur le fichier effectuées, il faut le fermer avec la fonction membre
close() comme ceci :
flux.close();.
Voici le code pour ouvrir et fermer le fichier
test.txt qui se trouve dans le même répertoire que mon programme :
Code : C++ 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | #include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream fichier("test.txt", ios::in); // on ouvre le fichier en lecture
if(fichier) // si l'ouverture a réussi
{
// instructions
fichier.close(); // on ferme le fichier
}
else // sinon
cerr << "Impossible d'ouvrir le fichier !" << endl;
return 0;
}
|
Ouverture en écriture : ofstream
Pour ouvrir le fichier en écriture, il faut également un flux agissant le fichier. Pour l'ouverture, on peut utiliser soit la fonction
open soit par la déclaration directe, qui, comme vous le savez, prennent deux paramètres : le nom du fichier ainsi que le mode d'ouverture.
Pour l'écriture, il y a différents modes d'ouverture, et si on ne fait pas attention, on peut perdre tout ce qu'il y a dans le fichier si celui-ci n'est pas vide.
Les modes d'ouverture sont :
- ios::out (pour output) : spécifie qu'on ouvre le fichier en écriture. Obligatoire - mais par défaut - quand on utilise un objet ofstream ;
- ios::app (pour append = ajouter à la suite) : lorsqu'on ouvre le fichier en écriture, on se trouve à la fin pour écrire des données à la suite du fichier (sans effacer le contenu, s'il y en a un). Avec ce mode d'ouverture, à chaque écriture, on est placé à la fin du fichier, même si on se déplace dans celui-ci avant (on verra comment se déplacer un peu plus tard
);
- ios::trunc (pour truncate = tronquer) : lorsqu'on ouvre le fichier en écriture, spécifie qu'il doit être effacé s'il existe déjà, pour laisser un fichier vide ;
- ios::ate (pour at end) : ouvre le fichier en écriture et positionne le curseur à la fin de celui-ci. La différence avec ios::app est que si on se repositionne dans le fichier, l'écriture ne se fera pas forcément à la fin du fichier, contrairement à ios::app.
Pour ces modes d'ouverture, si le fichier n'existe pas ou s'il n'est pas trouvé, il sera créé.
Il faut toujours indiquer un des trois modificateurs ios::trunc ou ios::app ou encore ios::ate, en plus de ios::out, pour spécifier la procédure à suivre au cas où le fichier existerait déjà.
Pour spécifier plusieurs modes d'ouverture, on utilise l'opérateur "ou" : | (prononcé
pipe en anglais). Sur un clavier, c'est la combinaison de touches Alt Gr et 6.
Voici le code qui ouvre en écriture le fichier
test.txt, qui efface le contenu du fichier s'il n'est pas vide et qui le referme :
Code : C++ 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | #include <iostream>
#include <fstream>
using namespace std;
int main()
{
ofstream fichier("test.txt", ios::out | ios::trunc); //déclaration du flux et ouverture du fichier
if(fichier) // si l'ouverture a réussi
{
// instructions
fichier.close(); // on referme le fichier
}
else // sinon
cerr << "Erreur à l'ouverture !" << endl;
return 0;
}
|
Ouverture en lecture ET en écriture : fstream
En utilisant
fstream, on ouvre en lecture et en écriture un fichier. Le fonctionnement est le même que pour
ifstream ou
ofstream.
Le prototype pour utiliser cette méthode d'ouverture est :
fstream flux("fichier.extention", ios::in | ios::out | [ios::trunc | ios::ate]);.
Pourquoi les crochets ?
C'est pour indiquer qu'il faut utiliser
un des deux, en fonction de ce qu'on veut faire.
- C'est l'unique moyen pour ouvrir le fichier en lecture-écriture !
- Il ne faut pas mettre les crochets une fois la méthode d'ouverture choisie (ios::app, ios::trunc ou ios::ate) !
- Vous avez avez peut-être remarqué qu'il n'y a pas la possibilité de mettre ios::app. En effet, il ne peut être utilisé que si on fait des écritures ; or, l'ouverture avec fstream permet la lecture ET l'écriture.
Avec ce mode d'ouverture, le fichier
DOIT exister ! Le
ios::in | ios::out est obligatoire pour bien spécifier que l'on ouvre le fichier en lecture ET en écriture. Comme le fichier est ouvert en écriture et qu'il existe déjà, il faut rajouter soit
ios::ate pour ne pas effacer le contenu, soit
ios::trunc pour l'effacer.
Et maintenant, une chose bien utile !
Si vous avez votre nom de fichier stocké dans une chaîne de caractères, et vous voulez que
fichier.extension prenne cette valeur, comment faites-vous ?
Si vous essayez de mettre à la place du nom de fichier le nom de votre chaîne, ça ne marche pas !
Pour le faire fonctionner, il faut rajouter
.c_str() après le nom de la chaîne. Ce
c_str() est une fonction membre de la librairie
string qui va renvoyer un pointeur vers un tableau de caractères (comme en langage C

).
Voici un exemple :
Code : C++ 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | #include <fstream>
#include <string>
using namespace std;
int main()
{
string mon_fichier = "test.txt"; // je stocke dans la chaîne mon_fichier le nom du fichier à ouvrir
ifstream fichier(mon_fichier.c_str(), ios::in);
if(fichier) // si l'ouverture a réussi
{
// instructions
fichier.close(); // je referme le fichier
}
else // sinon
cerr << "Erreur à l'ouverture !" << endl;
return 0;
}
|
Ce code ouvre en lecture le fichier
test.txt.
Voilà, vous savez ouvrir un fichier texte avec différents modes, tester l'ouverture et fermer le fichier.