Programmer en C++
Les fichiers

1. Introduction

Jusqu'à présent nous ne savions sauvegarder nos données que dans des variables. L'inconvénient de cette méthode est que le contenu de ces variables disparait à la fermeture du programme. Voyons maintenant comment conserver des données dans la durée, même si le fonctionnement de l'ordinateur est temporairement suspendu.
Nous allons stocker ces données dans des fichiers. sachez pour commencer que la manipulation de fichier nécessite un en-tête particulier :

#include <fstream>

1. Création d'un fichier

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    string const nomFichier("test.txt");
    ofstream monFlux(nomFichier.c_str());
}

Voilà c'est tout. La première ligne crée un nom de fichier. La deuxième ligne crée le fichier. Toutefois attention : Si un fichier existe déjà portant un nom identique, il sera alors écrasé par le nouveau.
Par prudence avant de travailler avec un fichier, il est recommandé de vérifier qu'aucun problème n'est survenu. Il suffit juste de tester monFlux de cette façon :

if(monFlux)
{
    // On continue
}
else
{
    // Abandon
}

Maintenant que le fichier est créé, cherchons à y placer du contenu. La technique est la même qu'avec "cout", sauf qu'au lieu d'envoyer vers l'écran, nous envoyons vers le fichier. On écrira le code suivant dans la partie précédente "// On continue". Le fichier peut être facilement ouvert avec le bloc-notes (voir ci-dessous).

monFlux << "Une jolie phrase" << endl;
float nombre(45.89);
monFlux << nombre << endl;
bool condition(true);
monFlux << condition << endl;

3. Ajout dans un fichier

Dans la partie précédente, chaque ouverture du fichier écrasait le précédent. Si nous désirons ajouter des données sans effacer les données précédentes, il nous faut alors modifier la ligne où nous avons déclaré "monFlux";

ofstream monFlux(nomFichier.c_str(), ios::app);

Voyons maintenant un exemple complet :

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    string const nomFichier("test.txt");
    ofstream monFlux(nomFichier.c_str(), ios::app);
    if(monFlux)
    {
        // On continue
        monFlux << "On ajoute cette phrase au fichier." << endl;
    }
    else
    {
        // Abandon
        cout << "Erreur d'enregistrement." << endl;
    }
}

Retrouvons notre fichier avec cette fois l'ajoût enregistré par le programme précédent.

4. Lecture d'un fichier

Dans cette partie, nous analyserons 3 modes de lecture d'un fichier :

En savoir plus

4.1. Lecture d'un fichier ligne par ligne

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

int main()
{
    string const nomFichier("test.txt");
    ifstream monFlux(nomFichier.c_str());
    if(monFlux)
    {
        // On continue
        string ligne;
        while (getline(monFlux, ligne))
        {
            cout << ligne << endl;
        }
    }
    else
    {
        // Abandon
        cout << "Erreur de lecture." << endl;
    }
}

Comme précédemment nous déclarons une chaine de caractère contenant le nom du fichier. Par contre pour lire ce fichier, nous utilisons cette fois "ifstream" (input file stream) à la place de "ofstream" (output file stream). Nous testons ensuite la variable monFlux pour nous assurer que tout c'est bien passé. Si c'est le cas, nous déclarons la chaine de caractère "ligne". A chaque appel de la fonction "getline", une ligne du fichier est lue, puis stockée dans la variable ligne. Ce qui est intéressant ici, c'est que si nous avons atteint la fin du fichier, la fonction "getline" retourne "false" au lieu de "true" quand il y a encore des informations à lire. La boucle "while" est donc indispensable pour nous permettre la lecture séquentielle et complète, ligne par ligne, de notre fichier.

4.3. Lecture d'un fichier caractère par caractère

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

int main()
{
    string const nomFichier("test.txt");
    ifstream monFlux(nomFichier.c_str());
    if(monFlux)
    {
        // On continue
        char c;
        while (monFlux.get(c))
        {
            cout << c;
        }
    }
    else
    {
        // Abandon
        cout << "Erreur de lecture." << endl;
    }
}

Le programme est très similaire au précédent. Ici on déclare un caractère "char" au lieu d'une chaine de caractère "string". Le caractère est obtenu grâce à la fonction get().