Annonce

Réduire
Aucune annonce.

Cours langage C n°14 - Les fichiers

Réduire
Ceci est une discussion importante.
X
X
 
  • Filtre
  • Heure
  • Afficher
Tout nettoyer
nouveaux messages

  • Cours langage C n°14 - Les fichiers

    Les fichiers

    Précédemment nous avons donné des informations par deux sources
    1. Soit la structure du programme
    2. Soit par l'utilisateur du programme (scanf, fgets, ... par exemple)


    Si je devais enregistrer des données de manière permanente, les deux solutions ci-dessus ne semblent pas nous arranger, on a donc comme autre solution, l'enregistrement de ces données dans un fichier.

    En algorithmie un fichier à traiter, doit être structuré et sont souvent délimité par des caractères connus à l'avance comme le point-virgule, la virgule, l'espace, ...
    Ce genre de fichier pourra être analysé et modifié sans grande difficulté en enregistrant et en le mettant à jour.

    Hors algorithmie, se sont de simples fichiers textes que l'on utilisera pour lire et l'analyser statistiquement, mais pas pour enregistrer une quelconque donnée.

    Vous aurez compris que le réel intérêt du fichier texte, est bien de le lire, de le modifier et surtout de réenregistrer, mettre à jour les données.

    Déclarer et initialiser le type FILE

    FILE ? Qu'est-ce ? C'est une structure, souvenez-vous, une structure est un tableau contenant des informations sur l'objet, dans notre cas le fichier.

    Comment se déclare ce type ?

    Très simple, enfin presque...

    Code:
    FILE *f = NULL;
    Hmmm, tu m'as bien dis que c'était une structure ? Oui ! Alors pourquoi le terme struct n'est pas devant FILE ?

    Très bonne question, en fait on a utiliser le mot clé typedef pour donner un synonyme et éviter de se coltiner le mot clé struct à chaque déclaration de variable.

    FILE *f, veut dire que l'on crée une variable nommée f, contenant l'adresse (et non la valeur) de la structure FILE, ici NULL.

    Ouvrir et fermer un fichier texte

    Pour ouvrir un fichier texte, on utilisera la fonction fopen, et comme vous pouvez le voir dans la documentation, son prototype est :

    Code:
    FILE * fopen ( const char * filename, const char * mode );
    Ok, donc je vois mieux pourquoi on déclare une adresse sur structure et non la structure elle même. fopen retourne une adresse sur structure

    Cette fonction prend aussi deux paramètres
    • Le chemin du fichier sous forme de chaîne de caractères
    • Le mode sous forme de chaîne de caractères qui prendra dans notre cas les valeurs "r", "w" et "a"


    Les modes:
    • "r" pour le mode de lecture
    • "rb" pour le mode de lecture fichier binaire
    • "w" pour le mode d'écriture fichier, le fichier sera écrasé si existant, sinon créé et écris
    • "wb" pour le mode d'écriture fichier binaire, le fichier sera écrasé si existant, sinon créé et écris
    • "a" pour le mode ajout, permet d'ajouter en fin de fichier, les caractères, chaînes de caractères, ...
    • "ab" idem que le mode "a", pour les fichiers binaires


    Revenons à nos moutons, pour ouvrir un fichier on utilise la fonction fopen et on va vérifier que ce fichier est bien ouvert en vérifiant que l'adresse de retour n'a pas pour valeur NULL, en code ça donne ceci

    Code:
    #include <stdio.h>
    
    int main(void)
    {
        FILE *f = fopen("test.txt", "r");
    
        if (f != NULL)
            puts("fichier ouvert !"); /* Affiche 'fichier ouvert' si fopen à réussi */
    
        return 0;
    }
    Ok, on sait ouvrir un fichier, mais si on l'ouvre il faut aussi savoir le fermer !

    Donc notre code sera final et correct sera celui ci-dessous en utilisant la fonction fclose (vous l'aurez deviné) dont le prototype est le suivant:

    Code:
    int fclose ( FILE * stream );
    Code:
    #include <stdio.h>
    
    int main(void)
    {
        FILE *f = fopen("test.txt", "r");
    
        if (f != NULL)
        {
            puts("fichier ouvert !");
            fclose(f);
            puts("fichier fermé !");
        }
    
        return 0;
    }
    C'est très important de ne pas l'oublier, ça laisse des traces en mémoire et ce n'est pas propre. La rigueur ne l'oubliez pas est importante en C.

    Lire un fichier texte

    Pour lire un fichier, on aura deux solutions, soit lire
    • ligne par ligne (avec fgets)
    • caractère par caractère (avec fgetc)


    Évidemment tout cela va dépendre de vos besoins, mais si c'est pour détecter le caractère de fin de ligne '\n', autant choisir la fonction fgets.

    Voici le code simple pour lire un fichier texte entièrement sur la console

    Code:
    #include <stdio.h>
    
    int main(void)
    {
        FILE *f = fopen("test.txt", "r");
    
        char line[200];
        char *p = NULL;
    
        if (f == NULL)
        {
            puts("impossible d'ouvrir le fichier");
            return -1;
        }
    
        p = fgets(line, sizeof line, f);
        while (p != NULL)
        {
            printf("%s", line);
            p = fgets(line, sizeof line, f);
        }
    
        fclose(f);
    
        return 0;
    }
    On pourrait aussi lire caractère par caractère avec fgetc

    Code:
    #include <stdio.h>
    
    int main(void)
    {
        FILE *f = fopen("test.txt", "r");
    
        char c;
    
        if (f == NULL)
        {
            puts("impossible d'ouvrir le fichier");
            return -1;
        }
    
        c = fgetc(f);
        while (c != EOF)
        {
            putchar(c);
            c = fgetc(f);
        }
    
        fclose(f);
    
        return 0;
    }
    Bref c'est au choix, tout dépendra si on analyse dans un fichier un caractère spécifique ou une ligne entière...

    Écrire dans un fichier texte

    Pour écrire dans un fichier, on a deux modes
    • Le mode "w"
    • Le mode "a"


    Nous utiliserons le mode "w" pour créer un nouveau fichier et écrire dedans.

    La fonction utile pour écrire est la fonction fputs, dont le prototype est le suivant:

    Code:
    int fputs ( const char * str, FILE * stream );
    On voit que fputs prend deux arguments,
    1. une chaîne de caractères
    2. une adresse sur structure type FILE


    Voici un exemple simple:

    Code:
    #include <stdio.h>
    
    int main(void)
    {
        FILE *f = fopen("test.txt", "w");
    
        const char *line = "Bonjour ça va ?";
    
        if (f == NULL)
        {
            puts("impossible d'ouvrir le fichier");
            return -1;
        }
    
        fputs(line, f); /* écriture du contenu de la variable line dans f */
    
        fclose(f);
    
        return 0;
    }
    Vous pouvez vérifier le fichier test.txt, normalement le contenu du fichier est le suivant: Bonjour ça va ?

    Pour écrire un seul caractère, nous utiliserons la fonction fputc, dont le prototype est le suivant :

    Code:
    int fputc ( int character, FILE * stream );
    Son utilisation est simple, en prenant l'exemple précédent, on arrive à ce code équivalent

    Code:
    #include <stdio.h>
    
    int main(void)
    {
        FILE *f = fopen("test.txt", "w");
    
        const char *line = "Bonjour ça va ?";
    
        int i;
    
        if (f == NULL)
        {
            puts("impossible d'ouvrir le fichier");
            return -1;
        }
    
        for (i=0; line[i] != '\0'; i++)
            fputc(line[i], f); /* écriture caractère par caractère dans le fichier */
    
        fclose(f);
    
        return 0;
    }
    EXERCICES

    Considérons cette ligne: Je;suis;hackadémicien;et;fier;de;l'être dans un fichier texte, nommé test.txt

    On vous demande de réécrire cette ligne dans le même fichier, en la modifiant sous cette forme: Je suis hackadémicien et fier de l'être

    Cela impose que la ligne de départ n'existe plus et est remplacée par cette dernière (remplacement des points-virgules par des espaces)

    Merci de m'avoir lu et à bientôt pour le prochain cours
    Dernière modification par fred, 04 septembre 2014, 08h31.

  • #2
    Bonjour,

    C'est un peu bricolo' mais bon

    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
    
        char citation[100] = "Je;suis;hackademicien;et;fier;de;l;etre";
        int i = 0;
    
        FILE *f = fopen("test.txt","w");
    
    
        if (f == NULL)
        {
            printf("impossible d'ouvrir le fichier");
            return -1;
        }
    
        fputs(citation,f);
        fclose(f);
    
        fopen("test.txt","w");
    
        while( citation[i] != '\0')
        {
            if(citation[i] == ';')
            {
                fputc(' ',f);
            }
            else
            {
                fputc(citation[i],f);
            }
            i++;
        }
    
        fclose(f);
    
        return 0;
    
    }
    deux et deux font cinq

    Commentaire


    • #3
      Non, non faut lire le fichier contenant cette chaîne, ce qui impose de créer un fichier txt contenant la chaîne Je;suis;hackademicien;et;fier;de;l;etre

      Commentaire


      • #4
        Exercice :

        Code:
        #include <stdio.h>
        
        int main(void)
        {
            FILE *f = fopen("test.txt", "r");
        
            char c;
            int i = 0;
            char line[200];
        
            if (f == NULL)
            {
                puts("Impossible d'ouvrir le fichier");
                return -1;
            }
        
            c = fgetc(f);
            while (c != EOF)
            {
                if (c == ';') /* On remplace les ; par des espaces. */
                    c = ' ';
                line[i] = c; /* On stocke la nouvelle ligne au fur et à mesure */
                i++;
                putchar(c);
                c = fgetc(f);
        
            }
        
            fclose(f);
        
            f = fopen("test.txt", "w");
        
            i = 0;
        
            if (f == NULL)
            {
                puts("Impossible d'ouvrir le fichier");
                return -1;
            }
        
            for (i=0; line[i] != '\0'; i++)
                fputc(line[i], f); /* On la réécrit ! */
        
            fclose(f);
        
            return 0;
        }
        Y aura-t-il encore des chapitres de cours ou il est fini ? Merci en tout cas !
        Mon blog : http://rootsheep.info

        Commentaire


        • #5
          Il y a un oubli, déjà une erreur que tu avais faîtes

          Y aura-t-il encore des chapitres de cours ou il est fini ? Merci en tout cas !
          Il y en aura, mais je n'ai absolument pas le temps actuellement pour en refaire, ça me prend beaucoup de temps à rendre ces cours pédagogiques et efficaces. Je pense que ça pourrait venir pour des vacances scolaires, mais avec mes projets actuels au boulot, vers juin, juillet je pense.

          En tout cas les cours que tu as lu, j'espère t'auront donné des bases suffisantes pour continuer à avancer toi même... Si tu as des soucis, le forum est là, tu auras sans doute une réponse de ma part. Si tu vois que je ne répond pas, tu peux me MP si tu veux.

          Commentaire


          • #6
            J'ai oublié un
            Code:
            fputc('\0',f);
            Lors de la réécriture c'est ça ? x) Faut que je prenne l'habitude, ça ne se voit pas du coup je m'en souviens jamais... :/
            Mon blog : http://rootsheep.info

            Commentaire


            • #7
              Non c'est quand tu finalises la création de ta variable line où l'erreur effectivement est un oubli d'une fin de chaîne

              Commentaire


              • #8
                Bonsoir Fred,

                Y aura t'il de nouveaux cours (n°15...) ? En tout cas merci chapeau pour le travail effectué jusque là, je compte suivre ton cours en parallèle de celui sur OpenClassrooms, que j'ai bien attaqué, mais qui me perd un peu (et manque d'incitation à la pratique je trouve).

                Merci !

                Commentaire

                Chargement...
                X