Chapitre 6 : LES FICHIERS Fichier Un fichier (angl.: file) est un ensemble stru
Chapitre 6 : LES FICHIERS Fichier Un fichier (angl.: file) est un ensemble structuré de données stocké en général sur un support externe (usb, disque dur, disque optique, bande magnétique, ...). Nous vous proposons ici d'étudier les fonctions permettant au programme d'échanger des informations avec des "fichiers'' En C, comme d'ailleurs dans d'autres langages, tous les périphériques, qu'ils soient d'archivage (disque,usb , . . . ) ou de communication (clavier, écran, imprimante,...), peuvent être considérés comme des fichiers. Rappelons que l'on distingue traditionnellement deux techniques de gestion de fichiers : - l'accès séquentiel consiste à traiter les informations "séquentiellement", c'est-à-dire dans l'ordre où elles apparaissent (ou apparaîtront) dans le fichier, les enregistrements sont mémorisés consécutivement dans l'ordre de leur entrée et peuvent seulement être lus dans cet ordre - - l'accès direct consiste à se placer immédiatement sur l'information souhaitée, sans avoir à parcourir celles qui la précèdent. Fichier séquentiel Les fichiers séquentiels que nous allons considérer dans ce cours auront la propriété suivante: * Les fichiers se trouvent ou bien en état d'écriture ou bien en état de lecture ; nous ne pouvons pas simultanément lire et écrire dans le même fichier. Fichiers standards Il existe deux fichiers spéciaux qui sont définis par défaut pour tous les programmes: - stdin le fichier d'entrée standard - stdout le fichier de sortie standard En général, stdin est lié au clavier et stdout est lié à l'écran, c.-à-d. les programmes lisent leurs données au clavier et écrivent les résultats sur l'écran. CRÉATION SÉQUENTIELLE D'UN FICHIER Voici un programme qui se contente d'enregistrer séquentiellement dans un fichier une suite de nombres entiers qu'on lui fournit au clavier. #include <stdio.h> int main(void) { char nomfich[21] ; int n ; FILE * sortie ; printf ("nom du fichier à créer : ") ; scanf ("%20s", nomfich) ; sortie = fopen (nomfich, "w") ; do { printf ("donnez un entier : ") ; scanf ("%d", &n) ; if (n) fwrite(&n, sizeof(int), 1, sortie) ; } while (n) ; fclose (sortie) ; return 0 ; } La déclaration : FILE * sortie signifie que sortie est un pointeur sur un objet de type FILE. La fonction fopen est ce que l'on nomme une fonction d'ouverture de fichier. Elle possède deux arguments : - le nom du fichier concerné, fourni sous forme d'une chaîne de caractères; ici, nous avons prévu que ce nom ne dépassera pas 20 caractères (le chiffre 21 tenant compte du caractère \0); notez qu'en général ce nom pourra comporter une information (chemin, répertoire,...) permettant de préciser l'endroit où se trouve le fichier. - une indication, fournie elle aussi sous forme d'une chaîne, précisant ce que l'on souhaite faire avec ce fichier. Ici, on trouve w (abréviation de write) qui permet de réaliser une "ouverture en écriture". Plus précisément, si le fichier cité n'existe pas, il sera créé par fopen. fwrite (&n, sizeof(int), 1, sortie); La fonction fwrite possède quatre arguments précisant : - l'adresse d'un bloc d'informations (ici &n), - la taille d'un bloc, en octets : ici sizeof(int); notez l'emploi de l'opérateur sizeof qui assure la portabilité du programme, - le nombre de blocs de cette taille que l'on souhaite transférer dans le fichier (ici l), - l'adresse de la structure décrivant le fichier (sortie). Notez que, d'une manière générale, fwrite permet de transférer plusieurs blocs consécutifs de même taille à partir d'une adresse donnée. Enfin, la fonction fclose réalise ce que l'on nomme une "fermeture" de fichier. Elle force l'écriture sur disque du tampon associé au fichier Remarque : 1) On emploie souvent le terme flux (en anglais stream) pour désigner un pointeur sur une structure de type FILE. Ici, par exemple, sortie est un flux que la fonction fopen aura associé à un certain fichier. D'une manière générale, par souci de simplification, lorsque aucune ambiguïté ne sera possible, nous utiliserons souvent le mot fichier à la place de flux 2) fopen fournit un pointeur nul en cas d'impossibilité d'ouverture du fichier. Ce sera le cas, par exemple, si l'on cherche à ouvrir en lecture un fichier inexistant ou encore si l'on cherche à créer un fichier sur une disquette saturée. 3) fwrite fournit le nombre de blocs effectivement écrits. Si cette valeur est inférieure au nombre prévu, cela signifie qu'une erreur est survenue en cours d'écriture. Cela peut être, par exemple, une disquette pleine, mais cela peut se produire également lorsque l'ouverture du fichier s'est mal déroulée (et que l'on n'a pas pris soin d'examiner le code de retour de fopen). LECTURE SÉQUENTIELLE D'UN FICHIER Voici maintenant un programme qui permet de lister le contenu d'un fichier quelconque tel qu'il a pu être créé par le programme précédent. #include <stdio.h> int main(void) { char nomfich[21] ; int n ; FILE * entree ; printf ("nom du fichier à lister : ") ; scanf ("%20s", nomfich) ; entree = fopen (nomfich, "r") ; while ( fread (&n, sizeof(int), 1, entree), ! feof(entree) ) { printf ("\n%d", n) ; } fclose (entree) ; return 0 ; } Les déclarations sont identiques à celles du programme précédent. En revanche, on trouve cette fois, dans l'ouverture du fichier, l'indication r (abréviation de read). Elle précise que le fichier en question ne sera utilisé qu'en lecture. Il est donc nécessaire qu'il existe déjà (nous verrons un peu plus loin comment traiter convenablement le cas où il n'existe pas). La lecture dans le fichier se fait par un appel de la fonction fread: Cette fonction lit les données depuis un flux. fread (&n, sizeof(int), 1, entree) dont les arguments sont comparables à ceux de fwrite. Le nombre d’octet lue est ( n*size) Les valeurs renvoyées par cette fonction sont : Si succèe : fread renvoie le nombre d’éléments lus Si EOF : fread renvoie une valeur inférieur n Dans notre cas Mais la condition d'arrêt de la boucle est: feof (entree). Celle-ci prend la valeur vrai (c'est-à-dire 1) lorsque la fin du fichier a été rencontrée. Remarques: 1) On pourrait remplacer la boucle while par la construction (moins concise) suivante: do { fread (&n, sizeof(int), 1, entree) ; if ( !feof(entree) ) printf ("\n%d", n) ; } while ( !feof(entree) ) ; 2) N'oubliez pas que le premier argument des fonctions fwrite et fread est une adresse. Ainsi, lorsque vous aurez affaire à un tableau, il faudra utiliser simplement son nom (sans le faire précéder de &), tandis qu'avec une structure il faudra effectivement utiliser l'opérateur & pour en obtenir l'adresse. Dans ce dernier cas, même si l'on ne cherche pas à rendre son programme portable, il sera préférable d'utiliser l'opérateur sizeof pour déterminer avec certitude la taille des blocs correspondants. 2) fread fournit le nombre de blocs effectivement lus (et non pas le nombre d'octets lus). Ce résultat peut être inférieur au nombre de blocs demandés soit lorsque l'on a rencontré une fin de fichier, soit lorsqu'une erreur de lecture est apparue. Dans notre précédent exemple Exemple 2 : Problème On se propose de créer un fichier qui est formé d'enregistrements contenant comme information le nom d'une personne. Chaque enregistrement est donc constitué d'une seule rubrique, à savoir, le nom de la personne. L'utilisateur doit entrer au clavier le nom du fichier, le nombre de personnes et les noms des personnes. Le programme se chargera de créer le fichier correspondant sur disque dur Après avoir écrit et fermé le fichier, le programme va réouvrir le même fichier en lecture et afficher son contenu, sans utiliser le nombre d'enregistrements introduit dans la première partie. Solution en langage C #include <stdio.h> main() { FILE *P_FICHIER; /* pointeur sur FILE */ char NOM_FICHIER[30], NOM_PERS[30]; int C,NB_ENREG; // Première partie : //Créer et remplir le fichier */ printf("Entrez le nom du fichier à créer : "); scanf("%s", NOM_FICHIER); P_FICHIER = fopen(NOM_FICHIER, "w"); /* write */ printf("Nombre d'enregistrements à créer : "); scanf("%d", &NB_ENREG); C = 0; while (C<NB_ENREG) { printf("Entrez le nom de la personne : "); scanf("%s", NOM_PERS); fprintf(P_FICHIER, "%s\n", NOM_PERS); C++; } fclose(P_FICHIER); // Deuxième partie : // Lire et afficher le contenu du fichier */ P_FICHIER = fopen(NOM_FICHIER, "r"); /* read */ while (!feof(P_FICHIER)) { fscanf(P_FICHIER, "%s\n", NOM_PERS); printf("NOM : %s\n", NOM_PERS); } fclose(P_FICHIER); return 0; } Ouvrir et fermer des fichiers séquentiels L'ouverture et la fermeture de fichiers se font à l'aide des fonctions fopen et fclose définies dans la bibliothèque standard <stdio>. Ouvrir un fichier en C - : fopen La fonction fopen Cette fonction, de type FILE* ouvre un fichier et lui associe un flot de données. Sa syntaxe est : fopen("nom-de-fichier","mode") La valeur retournée par fopen est un flot de données. Si l'exécution de cette fonction ne se déroule pas normalement, la valeur retournée est le pointeur NULL. Il est donc recommandé de toujours tester si la valeur renvoyée par la fonction fopen est égale à NULL afin de détecter les erreurs (lecture d'un fichier inexistant...). Le premier argument de fopen est le nom du fichier concerné, fourni sous forme d'une chaîne de caractères.. Le second argument, mode, est une chaîne de caractères uploads/Litterature/ chapitre-6-les-fichiers.pdf
Documents similaires
-
21
-
0
-
0
Licence et utilisation
Gratuit pour un usage personnel Attribution requise- Détails
- Publié le Mar 23, 2021
- Catégorie Literature / Litté...
- Langue French
- Taille du fichier 0.0858MB