Vous êtes sur la page 1sur 15

Page - 1

Chapitre 8 : Les fichiers


Table of Contents
Introduction............................................................................................................................................. 2
I. Types de fichiers .............................................................................................................................. 2
1. Fichier texte ................................................................................................................................. 2
2. Fichier binaire .............................................................................................................................. 2
3. Exemple ....................................................................................................................................... 2
II. Ouverture et fermeture d’un fichier ............................................................................................... 3
1. Nom d’un fichier .......................................................................................................................... 3
2. Ouverture d’un fichier ................................................................................................................. 3
3. Type File*..................................................................................................................................... 4
4. Test d’ouverture du fichier .......................................................................................................... 4
5. Fermeture d’un fichier ................................................................................................................ 5
6. Détection de fin de fichier ........................................................................................................... 6
a. Avec la fonction feof() ............................................................................................................. 6
b. Avec EOF .................................................................................................................................. 6
III. Ecriture dans un fichier texte ...................................................................................................... 6
1. La fonction fputc.......................................................................................................................... 7
2. La fonction fputs .......................................................................................................................... 7
3. La fonction fprintf ........................................................................................................................ 8
IV. Lecture d’un fichier texte ............................................................................................................ 8
1. La fonction fgetc .......................................................................................................................... 8
2. La fonction fgets .......................................................................................................................... 9
3. La fonction fscanf ...................................................................................................................... 11
V. Ecriture d’un fichier binaire ........................................................................................................... 12
VI. Lecture d’un fichier binaire ....................................................................................................... 13
VII. Accès séquentiel et accès direct................................................................................................ 14
1. Accès séquentiel ........................................................................................................................ 14
2. Accès direct ............................................................................................................................... 14
a. La fonction ftell : position dans le fichier .............................................................................. 14
b. La fonction fseek : se positionner dans le fichier .................................................................. 14
c. La fonction rewind : retour au début .................................................................................... 15

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020


Page - 2

Introduction
En C, les communications d'un programme avec son environnement se font par l'intermédiaire de
fichiers. Pour le programmeur, tous les périphériques, même le clavier et l'écran, sont des fichiers.
Jusqu'ici, nos programmes ont lu leurs données dans le fichier d'entrée standard, (c.-à-d.: le clavier)
et ils ont écrit leurs résultats dans le fichier de sortie standard (c.-à-d.: l'écran). Nous allons voir dans
ce chapitre, comment nous pouvons créer, lire et modifier nous-mêmes des fichiers sur disque.

I. Types de fichiers
Un fichier est un ensemble structuré de données stocké en général sur un support externe
(disquette, disque dur, disque optique, bande magnétique, ...).

1. Fichier texte
• Un fichier texte est une suite de caractères stockés avec leur code ASCII
o Les programmes source du langage C, par exemple, sont des fichiers texte.
• Un fichier texte est divisé en lignes qui se terminent par le caractère de retour à la ligne ‘\n’.
• Lisible : un fichier texte peut être créé ou consulté par l'utilisateur à l'aide d'un éditeur de texte
ou un programme.

2. Fichier binaire
• Tout ce qui n’est pas un fichier texte est un fichier binaire
• Un fichier binaire peut contenir toute sorte d’information y compris les données texte
• Un fichier binaire est une suite d’octets les uns derrière les autres sans aucune interprétation
o les caractères de contrôle (‘\n’, ‘\r’, etc) se sont pas interprétés
• Les données ne peuvent pas être lues/écrites que par programme.
• La taille du fichier est optimale (plus petite qu’un fichier texte) et les données sont facilement
lues/écrites en peu d’instructions.

3. Exemple
On écrit la suite des données suivantes, séparées par un espace, dans un fichier texte essai.txt et un
fichier binaire essai.bin

Un double qui vaut -1.60217e-19;

Un entier short qui vaut - 25724;

Une chaine de caractères qui vaut: « hello ! »

Une capture d’écran des deux fichiers donne :

On remarque que le fichier binaire est non lisible.

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020


Page - 3

II. Ouverture et fermeture d’un fichier


Pour manipuler un fichier, quel que soit le type d'accès envisagé (binaire ou texte), il faut suivre la
même procédure :

• ouvrir le fichier (fonction fopen) ; on indique le nom du fichier et les détails de l'accès envisagé.
• lire ou écrire dans le fichier : on utilise les fonctions autorisées par l'accès choisi (binaire ou
texte).
• fermer le fichier (fonction fclose).

1. Nom d’un fichier


• Un fichier est identifié par son nom qui est une chaine de caractères.
• Un nom de fichier contient des informations sur le chemin d’accès du fichier

Exemple :

Sous Windows, C:\data\liste.txt est un fichier qui se trouve dans le répertoire data .

Attention, en C le ‘\’ est un caractère spécial, il faut le déspécialiser. Ainsi dans le programme pour
définir une variable qui représente le nom du fichier on doit écrire ’\\’ :

char* nomFichier = "C:\\data\\liste.txt" ;

(NB : le type char* est à voir plus tard dans le cours)

• Eviter les accents et les espaces dans les noms de fichiers


• Chemin absolu : “/home/etudiant/tp1/ex1.txt“
• Chemin relatif (préférable) par rapport au répertoire où est exécuté le programme :
o "ex1.txt" ou "./ex1.txt" pour un fichier dans le répertoire courant
o "TP/ex1.txt" ou "./TP/ex1.txt" pour un fichier dans sous-répertoire TP
o "../ex1.txt" pour un fichier dans le répertoire supérieur

2. Ouverture d’un fichier


Pour l’ouverture d’un fichier on utilise la fonction fopen qui est défini dans stdio.h

FILE* fopen(const char* nomDuFichier, const char* modeOuverture);

Exemple :

FILE* f = fopen ("nomFichier.txt","w");

Cette fonction :

• Prend en paramètres le nom du fichier à ouvrir


• Le mode d’ouverture du fichier qui est une chaine de caractères de deux ou trois caractères qui
indiquent le mode d'accès choisi et le type de travail possible, choisi parmi :

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020


Page - 4

Mode d’ouverture Position Si fichier Si fichier


après déjà existant non existant
ouverture
"r" Lecture seule Début Erreur
(fopen
renvoie
NULL)

"w" Ecriture seule Début écrasement création

"a" Ecriture seule Fin erreur


(append)
"r+" Lecture/écriture Début erreur

"w+" Lecture/écriture Début écrasement création

"a+" Lecture/écriture Fin erreur

Remarque :

Le mode d’ouverture par défaut est le mode texte.

Si non veut ouvrir le fichier en mode binaire, il faut ajouter ‘b’ aux modes vus dans le tableau. On
aura donc : "rb", "wb", "ab", "rb+", "ab+".

3. Type File*
• La fonction fopen renvoie un pointeur sur le type FILE.
• Tout fichier du disque dur sera associé, une fois ouvert, à une variable de type FILE*, qui doit
être préalablement définie par :
FILE* f
• La variable f est un pointeur sur un objet de type FILE. Elle contient l’adresse en mémoire du
début du fichier.
• Le type FILE est un modèle de structure défini dans stdio.h et on l'appelle le « pointeur de
fichier ».

4. Test d’ouverture du fichier


• Juste après l'ouverture du fichier, il faut impérativement vérifier si l'ouverture a réussi ou non.
• En effet, si le pointeur vaut NULL, l'ouverture a échoué. S'il vaut autre chose que NULL,
l'ouverture a réussi.

Exemple :

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020


Page - 5

5. Fermeture d’un fichier


• Une fois que vous aurez fini de travailler avec le fichier, il faut le « fermer ».
• On utilise pour cela la fonction fclose qui a pour rôle de libérer la mémoire, c'est-à-dire
supprimer votre fichier chargé dans la mémoire vive.
• fclose est défini dans stdio.h comme :

int fclose(FILE* pointeurSurFichier);

• fclose renvoie un entier qui vaut :


o 0: si la fermeture a marché ;
o EOF: si la fermeture a échoué. EOF est une constante définie dans stdio.h.

Exemple :

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020


Page - 6

6. Détection de fin de fichier


• La lecture dans un fichier nécessite de détecter la fin du fichier.

a. Avec la fonction feof()


• La fonction feof renvoie une valeur non nulle lorsque la fin du fichier a été atteinte et renvoie la
valeur 0 dans le cas contraire. Son prototype est le suivant :

int feof(FILE * fic) ;

• Cette fonction est utilisable pour les fichiers en mode texte ou binaire.

b. Avec EOF
• On peut également utiliser la constante symbolique EOF définie dans stdio.h. EOF nous permet
de tester le caractère de fin de fichier. Si le caractère lu est EOF, alors ça correspond à la fin du
fichier.

• Attention : ceci est valide pour les fichiers en mode texte uniquement.

Exemple :

while ( (c=fgetc(fichier)) != EOF){


printf("%c", c) ;
}

III. Ecriture dans un fichier texte

Les principales fonctions disponibles pour l’écriture dans un fichier sont les suivantes :

• fputc(caractere, fichier); /* écriture d'un caractère */


• fputs(chaine, fichier); /* écriture d'une chaîne */
• fprintf(fichier, codes formats et texte, valeurs ); /*Ecriture
d’une chaine formatée*/
Ces fonctions sont définies dans stdio.h.

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020


Page - 7

1. La fonction fputc
Cette fonction écrit un caractère à la fois dans le fichier. Son prototype est :

int fputc(int caractere, FILE* pointeurSurFichier);

Elle prend deux paramètres.

• caractere: Le caractère à écrire (de type int)


• pointeurSurFichier: Le pointeur sur le fichier dans lequel écrire
• La fonction retourne le caractère écrit ou EOF s’il y a une erreur.
• Exemple : Le code suivant écrit la lettre 'A' dans test.txt (si le fichier existe, il est remplacé ;
s'il n'existe pas, il est créé). Il y a tout dans ce code : ouverture, test de l'ouverture,

int main {

FILE* fichier = NULL;

fichier = fopen("test.txt", "w");

if (fichier != NULL)

fputc('A', fichier); // Écriture du caractère A

fclose(fichier);

return 0;

2. La fonction fputs
Cette fonction est très similaire à fputc, à la différence près qu'elle écrit tout une chaîne, ce qui est
en général plus pratique que d'écrire caractère par caractère. Cela dit, fputc reste utile lorsque vous
devez écrire caractère par caractère, ce qui arrive fréquemment.

int fputs(const char* chaine, FILE* pointeurSurFichier);

La fonction fputs possède deux paramètres.

• chaine: la chaîne à écrire. Notez que le type ici est const char* puisque la chaine ne sera
pas modifiée par la fonction.
• pointeurSurFichier: il s'agit du pointeur sur le fichier ouvert.
La fonction renvoie une valeur non negative en cas de succès, et EOF s'il y a eu une erreur.

Exemple :
int main(int argc, char *argv[])
{
FILE* fichier = NULL;

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020


Page - 8

fichier = fopen("test.txt", "w");

if (fichier != NULL)
{
fputs("Salut tout le monde \n", fichier);
fclose(fichier);
}
return 0;
}

3. La fonction fprintf
La fonction fprintf peut être utilisée pour écrire dans un fichier. Elle s'utilise de la même manière que
printf, excepté le fait que vous devez indiquer un pointeur de FILE en premier paramètre. Fournit
le nombre de caractères effectivement écrits ou une valeur négative en cas d’erreur.

int fprintf (file *F, const char* format, expr1, expr2,…);

Exemple :

Ce programme demande l'âge de l'utilisateur et l'écrit dans le fichier test.txt.

int main(int argc, char *argv[])


{
FILE* fichier = NULL;
int age = 0;
fichier = fopen("test.txt", "w");
if (fichier != NULL)
{
printf("Quel age avez-vous ?"); // On demande l'âge
scanf("%d", &age);
// On l'écrit dans le fichier
fprintf(fichier, "La personne qui a %d ans", age);
fclose(fichier);
}

return 0;
}

IV. Lecture d’un fichier texte


Les fonctions disponibles pour la lecture d’un fichier sont :

• fgetc: lit un caractère ;


• fgets: lit une chaîne ;
• fscanf: lit une chaîne formatée.
Ces fonctions sont définies dans stdio.h.

1. La fonction fgetc
Lit un caractère à partir du fichier et retourne ce caractère en cas de succès, sinon renvoie EOF.

int fgetc(FILE* pointeurDeFichier);

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020


Page - 9

fgetc avance le curseur d'un caractère à chaque fois qu’on en lit un. Si vous appelez fgetc une
seconde fois, la fonction lira donc le second caractère, puis le troisième et ainsi de suite. Vous pouvez
donc faire une boucle pour lire les caractères un par un dans le fichier.

Exercice:

Ce programme lit tous les caractères d'un fichier un à un et les écrit à chaque fois à l'écran. La boucle
s'arrête quand fgetc renvoie EOF (qui signifie « End Of File », c'est-à-dire « fin du fichier »).

int main(int argc, char *argv[])


{
FILE* fichier = NULL;
int caractereActuel = 0;

fichier = fopen("test.txt", "r");

if (fichier != NULL)
{
caractereActuel = fgetc(fichier); // On lit le premier
caractère
// Boucle de lecture des caractères un à un
while (caractereActuel != EOF)
//On continue tant que fgetc n'a pas atteint la fin du
//fichier
{

printf("%c", caractereActuel); // On l'affiche

caractereActuel = fgetc(fichier); // On lit le caractère

}
fclose(fichier);
}
return 0;
}

2. La fonction fgets
La fonction lit au maximum une ligne (elle s'arrête au premier \n qu'elle rencontre).

char* fgets(char* chaine, int nbreDeCaracteresALire, FILE* f) ;

• La fonction lit au maximum nbreDeCaracteresALire-1 caractères du fichier, en s’interrompant


éventuellement en cas de rencontre d’un caractère \n,
• Elle s'arrête de lire la ligne si elle dépasse nbreDeCaracteresALire
• les range dans la chaîne d’adresse chine,
• puis complète le tout par un caractère \0. Le caractère \n, s’il a été lu, est lui aussi rangé dans la
chaîne (donc juste avant le \0).

Cette fonction fournit en retour :


• la valeur NULL si une éventuelle erreur a eu lieu ou si une fin de fichier a été rencontrée,
• l’adresse chaine, dans le cas contraire.

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020


Page - 10

Exemple :

On lit une ligne dans un fichier et on affiche cette ligne à l’écran. Pour cela, on crée une chaîne
suffisamment grande pour stocker le contenu de la ligne qu'on va lire.

#define TAILLE_MAX 1000

int main(int argc, char *argv[])


{
FILE* fichier = NULL;
char chaine[TAILLE_MAX] = ""; //Chaîne vide de taille TAILLE_MAX
fichier = fopen("test.txt", "r");
if (fichier != NULL)
{
fgets(chaine, TAILLE_MAX, fichier); // On lit au maximum
TAILLE_MAX-1 caractères du fichier, on stocke le tout dans "chaine"
printf("%s", chaine); // On affiche la chaîne
fclose(fichier);
}
return 0;
}

Exercice

Ecrire un code source qui lit et affiche tout le contenu d’un fichier, ligne par ligne.

Le fichier

Output du programme

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020


Page - 11

3. La fonction fscanf
Le prototype de la fonction fscanf est le suivant :

int fscanf (File *F, const char* format1,.., &expr1,…, &expN);

• F : est un pointeur du type FILE* qui est relié au nom du fichier à lire.
• <expr1>,..., <exprN> représentent les adresses des variables qui vont recevoir les valeurs lues
dans le fichier.
• <Format1>,..., <FormatN> représentent les spécificateurs de format pour la lecture des
différentes données.
• Lit les données à partir du fichier F et les stocke aux adresses indiquées.
• Retourne le nombre de données lues avec succès ou la valeur EOF si une erreur s’est produite ou
si la fin de fichier a été rencontrée avant qu’une seule valeur ait pu être lue.

Exemple

Le fichier test.txt à partir duquel la


fonction fscanf va lire

Tant que la fin du fichier n’est pas


atteinte : lire et afficher le contenu

la fonction fscanf attend une


chaine de caractère, suivie de
deux entiers("%s %d %d"). Elle les
stocke dans les variables name,
age, poids

Le résultat d’exécution

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020


Page - 12

V. Ecriture d’un fichier binaire


On peut utiliser la fonction fwrite dont le prototype est :

size_t fwrite(const void *source, size_t taille, size_t nombre, FILE *f)

• Ecrit tout un bloc de données en un seul appel et retourne le nombre d’éléments effectivement
écrits
• source : est un pointeur vers la région de la mémoire contenant les informations à écrire dans
le fichier. Ce pointeur est de type void*, c’est-à-dire qu’il peut pointer vers n’importe quoi
• taille : spécifie la taille (en nombre d’octets) des éléments à écrire
• nombre: le nombre des éléments à écrire
• Pour savoir si la fonction est exécutée sans erreur, on peut faire le test :
o if ((fwrite(source, taille, nombre)) != nombre)
printf("Erreur d’écriture sur disque") ;
• Exemples :
o Si on veut sauvegarder un tableau de 100 valeurs numériques de type int,
 taille = 4 : taille d’un entier en mémoire
• On peut utiliser l’opérateur sizeof pour connaître la taille du type à
écrire : sizeof(int)
 nombre = 100
o Pour écrire une seule variable x de type double dans un fichier
 double x ; fwrite(&x, sizeof(x), 1, fichier);
o Pour écrire un tableau data[] de 50 entiers, deux formes sont possibles :
 fwrite(data, sizeof(int), 50, fichier);
 fwrite(data, sizeof(data), 1, fichier);

Exercice: Ecrire un programme qui permet d’écrire un tableau et une chaine de caractères dans un
fichier binaire.

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020


Page - 13

Après exécution de ce programme, le fichier essai.bin est comme suivant :

VI. Lecture d’un fichier binaire


• La fonction fread permet la lecture d’un bloc de données en binaire et renvoie le nombre
d’éléments effectivement lus.

size_t fread(void *destination, size_t taille, size_t nombre, FILE


*fichier)

• destination : est un pointeur vers la région de la mémoire qui recevra les informations lues
à partir du fichier.
• taille: spécifie la taille (en nombre d’octets) des éléments à lire
• nombre : le nombre d’éléments à lire (comme pour la fonction fwrite)
• fichier : est un pointeur vers le fichier

Exercice :

Ecrire un programme qui permet de copier le contenu d’un tableau tab1 dans un fichier. Après le
programme doit copier le contenu du fichier dans un autre tableau tab2.

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020


Page - 14

Résumé

VII. Accès séquentiel et accès direct


On distingue deux modes d’accès aux fichiers :

1. Accès séquentiel
Consiste à traiter les informations "séquentiellement", c'est-à-dire dans l'ordre où elles apparaissent
dans le fichier. On parle d’un pointeur (sorte de curseur virtuel) qui avance à chaque fois qu’on lit ou
on écrit des octets du fichier. Par exemple, avec chaque appel à la fonction fgetc, le pointeur de
fichier avance d’une position vers la fin du fichier. On a le même comportement aussi pour l’écriture
avec fprintf.

2. Accès direct
L’accès direct consiste à se placer immédiatement sur l'information souhaitée, sans avoir à parcourir
celles qui la précèdent. Par exemple, cet accès nous permet de lire des octets au milieu du fichier
directement. Pour pouvoir faire cet accès aléatoire, on dispose de trois fonctions :

• ftell: renvoie la position dans le fichier;


• fseek: positionne le curseur à un endroit précis ;
• rewind: remet le curseur au début du fichier (c'est équivalent à demander à la fonction
fseek de positionner le curseur au début).

a. La fonction ftell : position dans le fichier


Cette fonction appartient à la bibliothèque stdio.h. Elle renvoie la position actuelle du curseur sous la
forme d'un long. Autrement dit, le nombre renvoyé indique le nombre d’octets séparant la position
actuelle du début du fichier. En cas d’erreur, la fonction envoie -1.

long ftell(FILE* pointeurSurFichier);

b. La fonction fseek : se positionner dans le fichier


Le prototype de fseek est le suivant :

int fseek(FILE* pointeurSurFichier, long deplacement, int origine);


La fonction fseek permet de déplacer le curseur d'un certain nombre de caractères (indiqué par
deplacement) à partir de la position indiquée par origine. La fonction fseek renvoie :

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020


Page - 15

• la valeur 0 lorsque le positionnement s’est déroulé correctement ;


• une valeur quelconque dans le cas contraire.
Le nombre deplacement peut être :
• un nombre positif (pour se déplacer en avant),
• 0 ou négatif (pour se déplacer en arrière).
Quant au nombre origine, vous pouvez mettre comme valeur l'une des trois constantes listées ci-
dessous:
o SEEK_SET: indique le début du fichier ;
o SEEK_CUR: indique la position actuelle du curseur ;
o SEEK_END: indique la fin du fichier.
Exemples :

• fseek(fichier, 2, SEEK_SET);
 Placer le curseur deux caractères après le début:
• fseek(fichier, -4, SEEK_CUR);
 Placer le curseur quatre caractères avant la position courante. Remarquez que
deplacement est négatif car on se déplace en arrière.
• fseek(fichier, 0, SEEK_END);
 Placer le curseur à la fin du fichier
Remarque :

Si vous écrivez dans le fichier après avoir fait un fseek qui mène à la fin du fichier, cela ajoutera vos
informations à la suite dans le fichier (le fichier sera complété).

En revanche, si vous placez le curseur au début et que vous écrivez, cela écrasera le texte qui se
trouvait là.

Exemple: Le programme suivant se place au 7ème caractère du fichier texte et écrit la chaine « C
Programming Language ». Ce qui fait que la ligne écrite initialement est mise à jour.

Donc ce programme affiche : «This is C programming langage»

c. La fonction rewind : retour au début


Cette fonction est équivalente à utiliser fseek pour nous renvoyer à la position 0 dans le fichier.
void rewind(FILE* pointeurSurFichier);
appeler rewind est équivalent à l’appel: fseek (pointeurSurFichier, 0, SEEK_SET);

© Ichrak Amdouni Programmation Procédurale et Langage C Eniso 2019-2020

Vous aimerez peut-être aussi