Lecture et écriture dans les fichiers en C++

Formation

À Paris

Prix sur demande

Appeler le centre

Avez-vous besoin d'un coach de formation?

Il vous aidera à comparer différents cours et à trouver la solution la plus abordable.

Description

  • Typologie

    Formation

  • Lieu

    Paris

Grâce à cette formation vous pourrez acquérir les connaissances nécessaires qui vous permettrons d’ajouter des compétences à votre profil et obtenir de solides aptitude qui vous offriront de nombreuses opportunités professionnelles.

Les sites et dates disponibles

Lieu

Date de début

Paris ((75) Paris)
Voir plan
7 Cité Paradis, 75010

Date de début

Consulter

Questions / Réponses

Ajoutez votre question

Nos conseillers et autres utilisateurs pourront vous répondre

À qui souhaitez-vous addresser votre question?

Saisissez vos coordonnées pour recevoir une réponse

Nous ne publierons que votre nom et votre question

Les Avis

Les matières

  • Écriture
  • C++
  • Lecture

Le programme

Introduction du cours

Bonjour à tous !

En naviguant sur divers sites, je me suis rendu compte que dans beaucoup de tutoriels et de cours censés être sur le C++, quand le chapitre sur les fichiers arrivait, la méthode donnée était en C et non en C++.
De plus, leurs auteurs n'indiquent même pas que c'est du C !!

Ce n'est quand même pas si compliqué que cela, et je vais vous le prouver ! ;)

Dans ce tutoriel, je vais vous montrer comment agir sur deux types de fichiers en C++. Dans son big-tuto, M@teo21 le montre en C mais pas (encore) en C++. :D

En fait, c'est la traduction en C++ du chapitre 7 de la partie 2 du tuto de M@teo21, mais j'ai quand même rajouté des choses ^^ .

Évidemment, il faut avoir les bases en C/C++. Le tuto de M@teo21 doit donc être lu ! Il est disponible ici.

Ouverture et fermeture d'un fichier

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 :

#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 :

#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; }
  • Quand on ouvre un fichier en lecture, le mode d'ouverture ios::in est facultatif. En effet, il est par défaut.

  • cerr est la sortie standard des erreurs. On peut aussi utiliser cout sans aucun problème.

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 :

#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 :

#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.

Lire et écrire dans un fichier texteLire le contenu d'un fichier

Alors, pour lire un fichier, il y a différentes méthodes qu'il faut employer en fonction de ce que l'on veut faire.
Les voilà :

  • getline(flux, chaineDeCaractères) : pour lire une ligne complète ;

  • flux.get(caractère) : pour lire un caractère ;

  • flux >> variable : pour récupérer à partir du fichier jusqu'à un délimiteur (espace, saut à la ligne, ...).

Il faut ouvrir le fichier en lecture ou en lecture-écriture, mais pas en écriture seule avec ofstream !

Commençons par getline

Avec cette fonction, on peut lire et afficher à l'écran une ligne du fichier ou bien le fichier en entier en utilisant une boucle.

Cette fonction prend deux paramètres : le flux que l'on crée avec ifstream ou fstream. Le deuxième paramètre est la "cible" dans laquelle vous allez stocker le contenu lu dans le fichier. En général, c'est une chaîne de caractères (string ;) ). Il faut donc inclure l'entête #include <string>.

Voici le code qui ouvre le fichier test.txt en lecture, affiche la première ligne et referme le fichier :

#include <iostream> #include <string> #include <fstream> using namespace std; int main() { ifstream fichier("test.txt", ios::in); // on ouvre en lecture if(fichier) // si l'ouverture a fonctionné { string contenu; // déclaration d'une chaîne qui contiendra la ligne lue getline(fichier, contenu); // on met dans "contenu" la ligne cout << contenu; // on affiche la ligne fichier.close(); } else cerr << "Impossible d'ouvrir le fichier !" << endl; return 0; }

Pour lire et afficher le fichier en entier, il faut le lire ligne par ligne et afficher à chaque fois la ligne lue.
On utilisera donc une boucle dont le contenu se répètera tant qu'il y a une ligne à lire. S'il n'y a plus de ligne, on sort de la boucle.

Dans le code précédent, il faut changer ce qu'il y a dans le if comme ceci :

if(fichier) { string ligne; while(getline(fichier, ligne)) // tant que l'on peut mettre la ligne dans "contenu" { cout << ligne << endl; // on l'affiche } }

Il existe encore une surcharge de cette fonction qui prend en troisième paramètre un caractère de fin. getline va alors lire le fichier jusqu'à trouver ce caractère de fin. Par défaut, ce caractère est égal au retour à la ligne ('\n'), c'est pour cela qu'on peut lire ligne par ligne sans spécifier ce troisième paramètre. Celui-ci est facultatif.

Bien, on en a fini avec getline.

Continuons avec get

Tout comme getline, cette fonction ne marche que si on a utilisé ifstream ou fstream comme flux. Ça ne fonctionne pas avec ofstream.

Cette fonction est utilisée pour lire un caractère, et un seul. Bien sûr, il est également possible d'afficher le texte en entier en utilisant une boucle.

En informatique, les espaces, retours à la ligne, retours chariot, ... sont considérés comme des caractères !

La syntaxe de cette fonction est : flux.get(caractère);. Ceci lit un caractère du fichier et le stocke dans caractere qui est de type char.

Le code suivant ouvre un fichier en lecture, lit un caractère, l'affiche, et referme le fichier :

#include <iostream> #include <fstream> using namespace std; int main() { ifstream fichier("test.txt", ios::in); // on ouvre if(fichier) { char caractere; // notre variable où sera stocké le caractère fichier.get(caractere); // on lit un caractère et on le stocke dans caractere cout << caractere; // on l'affiche fichier.close(); } else cerr << "Impossible d'ouvrir le fichier !" << endl; return 0; }

Pour lire le fichier en entier avec cette méthode, la boucle est la même que celle pour getline.

On en a fini avec get.

Terminons avec >>

Ce symbole ne devrait pas vous être inconnu : il est aussi utilisé pour cin. Le fonctionnement avec les fichiers est exactement le même. Cet opérateur lit dans le fichier jusqu'à ce qu'il trouve un délimiteur qui peut être un espace ou un retour à la ligne.

Après avoir lu le premier élément, si on réutilise cet opérateur,...

Appeler le centre

Avez-vous besoin d'un coach de formation?

Il vous aidera à comparer différents cours et à trouver la solution la plus abordable.

Lecture et écriture dans les fichiers en C++

Prix sur demande