Le langage C - fichiers

Un fichier est un espace réservé et nommé sur un support permanent comme le disque dur de l'ordinateur, qui sert à stocker des données par exemple pour pouvoir les réutiliser dans un autre programme. En C, il faut ouvrir un fichier (fopen) avant de pouvoir lire et écrire du texte (fscanf/fprintf) ou des données binaires (fread/fwrite), puis le fermer (fclose) quand on a fini de l'utiliser. Il existe d'autres commandes pour détruire, renommer, copier des fichiers, mais nous n'en parlons pas ici.

Lecture / écriture dans un fichier texte

Voici un exemple d'écriture dans un fichier texte:

FILE *fichier ;    /*  pointeur vers un type fichier     */
int i ;            /*  compteur de boucle                */
float x[25] ;      /*  tableau a ecrire dans le fichier  */

/*  ouverture du fichier 'mon_fichier.txt' pour ecriture (w) en mode texte (t)  */
fichier = fopen ("mon_fichier.txt", "wt") ;

/*  en cas d'échec de l'ouverture, le pointeur est NULL: intercepter ce cas  */
if (fichier == NULL) {
    /*  message d'alerte et fin du programme  */
    printf ("impossible de créer le fichier mon_fichier.txt\n") ;
    exit (0) ;
}

 /*  Il manque ici un calcul qui mettrait des valeurs intéressantes dans x[]  */

 /*  ecriture du tableau x  */
for (i=0 ; i<25 ; i++) {
    fprintf (fichier,"x[%d] = %f\n", i, x) ;
}

/*  fermeture du fichier  */
fclose (fichier) ;

La commande d'ouverture de fichier doit préciser, outre le nom du fichier, si on souhaite lire (read) ou écrire (write) dedans (ou les deux), et s'il s'agit de texte ou pas. Le résultat est en quelque sorte un pointeur vers notre fichier (pour être exact, un pointeur vers une structure FILE qui décrit notre fichier). C'est ce pointeur qu'on indique dans la commande d'écriture un peu plus loin (fprintf(...)) pour dire où on veut écrire (si l'on souhaite manipuler plusieurs fichiers, il suffit de réserver plusieurs pointeurs de type FILE *). Pour les autres arguments de la commande fprintf(), voir la description de la commande printf.

La dernière commande ferme le fichier.

La lecture d'un fichier est faite de manière tout-à-fait semblable, mais il peut être important de vérifier si les lectures individuelles on fonctionné ou pas:

FILE *fichier ;
int i ;
float x[25], y ;

/*  ouverture du fichier 'mon_fichier.txt' pour lecture (r) en mode texte (t)  */
fichier = fopen ("mon_fichier.txt", "rt") ;

/*  en cas d'échec de l'ouverture, le pointeur est NULL: intercepter ce cas  */
if (fichier == NULL) {
    /*  message d'alerte et fin du programme  */
    printf ("impossible de créer le fichier mon_fichier.txt\n") ;
    exit (0) ;
}

for (i=0 ; i<25 ; i++) /*  boucle pour lire dans le fichier */
{
    if (fscanf (fichier, "%f", &y) == 1) /* lecture d'un réel */
    {
        x[i] = y; /*  reussi => je le stocke */
    }
    else                                 /*  echec  */
    {
        printf ("erreur ligne %d\n", i) ;/*  message  */
        fclose (fichier) ;               /*  fermeture du fichier  */
        exit (0) ; /*  arret du programme  */
    }
}
fclose (fichier) ; /*  fermeture du fichier  */

Ressemblance entre printf et fprintf: héritage d'Unix

Les commandes pour lire et écrire dans un fichier texte (fprintf() et fscanf()) sont très semblables à celles qu'on utilise pour écrire à l'écran ou lire du clavier (printf() et scanf()). Et pour cause: c'est une trace du concept Unix "tout est un fichier". Ainsi, l'écran et le clavier sont aux yeux de votre ordinateur également deux fichiers, certes un peu spéciaux (pour les expérimentateurs: sous Linux, taper 'who' pour trouver le nom du "fichier écran" (en pts/N, N étant un entier), puis 'echo Coucou >/dev/pts/N' (à partir d'un autre terminal). La commande printf() est simplement traduite en un fprintf() sur ce fichier écran, qu'on appelle sortie standard. Vous pouvez aussi le faire explicitement:

fprintf(stdout,"%f",x);

pour afficher la valeur de la variable x est strictement équivalent au

printf("%f",x);

plus court et commode. En plus de la sortie standard (stdout), il existe deux autres pointeurs fichiers spéciaux: l'entrée standard (stdin) et la sortie erreur standard (stderr). Pour ces trois fichiers (et seulement eux), on n'a pas besoin de faire de fopen/fclose. Taper man stdout pour plus d'information.

Il est de bon usage d'afficher les messages d'erreur de votre programme non pas à l'aide de printf, mais en utilisant stderr:
fprintf(stderr, "Erreur d'allocation de mémoire, fatale.\n");
La sortie stardard normale reste ainsi réservée aux vrais résultats, ce qui permet de faire le tri.

En plus de la simplicité conceptuelle, cette unification a l'avantage qu'il est facile de faire écrire dans un fichier ce qu'un programme affiche à l'écran. Il suffit de remplacer avant le lancement du programme la valeur habituelle du pointeur stdout (pointeur vers le fichier écran) par un pointeur vers un vrai fichier. Cela s'appelle la redirection de sortie, Unix prévoit un mécanisme très simple pour le faire en ligne de commande (voir ces notes).

Lecture/écriture dans un fichier binaire

Tout ce qui change par rapport à la lecture et à l'écriture dans un fichier texte est qu'on omet le 't' dans le deuxième paramètre de fopen à l'ouverture du fichier, et qu'on utilise d'autre fonctions pour l'écriture et la lecture même, par exemple le coupe fread/fwrite. Comme avec toutes les fonction C standards, taper man fwrite vous donnera une documentation de son usage.

Auteur(s) : Anciens, A. Daerr. Dernière modification : Mon Apr 24 15:18:40 2006. [valid. XHTML]