Fichiers séquentiels - Université Laval

33
Fichiers séquentiels Définitions et propriétés des fichiers séquentiels. Mémoire tampon. Type « File ». Ouverture et fermeture d’un fichier, lecture et écriture dans un fichier. Traitement par enregistrements. Traitement par caractères. Formatage ou non des données. Déplacement à l’intérieur d’un fichier. Détection de la fin d’un fichier. Mise à jour d’un fichier : ajout, suppression ou modification d’un enregistrement. Fichiers temporaires.

Transcript of Fichiers séquentiels - Université Laval

Page 1: Fichiers séquentiels - Université Laval

Fichiers séquentiels

Définitions et propriétés des fichiers séquentiels. Mémoire tampon.Type « File ». Ouverture et fermeture d’un fichier, lecture et écrituredans un fichier. Traitement par enregistrements. Traitement parcaractères. Formatage ou non des données. Déplacement à l’intérieurd’un fichier. Détection de la fin d’un fichier. Mise à jour d’un fichier :ajout, suppression ou modification d’un enregistrement. Fichierstemporaires.

Page 2: Fichiers séquentiels - Université Laval

2

IntroductionEn C, les communications d’un programme avec son environnement se fontpar l’intermédiaire de fichiers.

Même le clavier et l’écran sont des fichiers dits « standards ».

Nous pouvons donc créer, lire ou écrire dans des fichiers de différentspériphériques (disque dur, disquette, bande magnétique, …).

C fournit dans la librairie stdio.h un ensemble de fonctions pour gérerdes fichiers. Ces outils sont indépendants de l’unité utilisée.

Jusqu’à maintenant, les données traitées dans un programme sont perduesà la fin de l’exécution du programme. On peut remédier à ceci en stockantles données sur des unités de stockage permanent.

Exemple : Un programme dont le rôle est de gérer un carnet d’adressesdevrait à chaque fois entrer toutes les données de ce carnetd’adresses.

Page 3: Fichiers séquentiels - Université Laval

3

Concept de fichierUn fichier est un ensemble structuré de données stocké en général sur unsupport externe. Même si nous pouvons écrire en principe n’importe quel typede données, un programme qui lit un fichier doit interpréter les donnéescorrectement.Un fichier possède une position de début, une position de fin et une positioncourante.Chaque opération sur un fichier est effectuée sur les données en positioncourante.Une nouvelle position courante peut être obtenue en effectuant undéplacement à partir du début du fichier ou à partir de l’ancienne positioncourante.

Fichier séquentiel : Les données sont stockées consécutivement selon l’ordred’entrée et peuvent seulement être lues dans cet ordre.

Page 4: Fichiers séquentiels - Université Laval

4

Fichiers séquentielsCes 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.À un moment donné, on peut uniquement accéder à un seul enregistrement;celui qui se trouve en face de la tête de lecture / écriture (position courante).

Après chaque accès, la tête de lecture / écriture est déplacée à la suite dela donnée.

Pour des raisons d’efficacité, lesaccès à un fichier se font parl’intermédiaire d’une mémoiretampon («buffer») laquelle estune zone de mémoire réservéeà un ou plusieursenregistrements du fichier.

Cela permet de réduire le #d’accès au périphérique.

Page 5: Fichiers séquentiels - Université Laval

5

Ouverture et fermeture d’un fichierAvant de lire ou d’écrire dans un fichier, la commande fopen nous permetd’établir un lien entre le chemin d’accès au fichier sur le support externe(par ex. : "A:\Exemples de programmes\Fiches.dat") et un pointeur de fichierqui représente un nom de fichier logique.

Exemple : FILE * pFichier = NULL;pFichier = fopen("A:\\Exemples de programmes\\Fiches.txt", "r");

Chemin d’accèsau fichier sursupport externe

Nom dufichierlogique(pointeurde fichier)

Mode d’accès :- lecture ("r"),- écriture ("w"),- concaténation ("a"):

écrire à la fin du fichier.La commande fopen renvoie un pointeur vers une structure de type FILErenfermant : - l’adresse de la mémoire tampon,

- la position courante,- le mode d’accès, etc.

Nous n’avons pas à nous préoccuper de ces informations; le système d’ex-ploitation génère automatiquement ce bloc de type FILE et fournit l’adresse.

Page 6: Fichiers séquentiels - Université Laval

6

Ouverture et fermeture d’un fichier

Tout ce que nous avons à faire dans notre programme est :

déclarer un pointeur de type FILE * pour chaque fichier dont nous avonsbesoin,affecter l’adresse retournée par fopen à ce pointeur,

employer le pointeur à la place du nom du fichier dans toutes lesinstructions de lecture ou d’écriture,

libérer la mémoire tampon et annuler la liaison entre le pointeur et le nomdu fichier à la fin du traitement à l’aide de fclose : int fclose(pFichier);

fclose retourne EOF si une erreur est survenue; 0 autrement.Ouverture en écriture : les données non écrites de la mémoire tampon sont écrites.Ouverture en lecture : les données non lues de la mémoire tampon sont perdues.

Le premier paramètre de fopen est une chaîne de caractères, un tableau decaractères ou un pointeur de type char.

La valeur peut aussi être saisie au clavier ou définie comme constante audébut du programme.

Page 7: Fichiers séquentiels - Université Laval

7

Ouverture et fermeture d’un fichier#include <stdio.h>

void main(){

FILE * pFichier = NULL;pFichier = fopen("E:\\Nouveau_dossier\\Essai.txt", "w");

// Opérations d’entrées / sorties.

fclose(pFichier);}

Le mode "r" présuppose que le fichier existe déjà.

Le mode "w" crée le fichier s’il n’existe pas déjà;s’il existe déjà, les enregistrements du fichier sont perdus.Le mode "a" permet d’ajouter des données à la fin du fichier.Cela crée le fichier s’il n’existe pas déjà.

et non 'w'.

S’il n’existe pas, fopen retourne NULL.

Si l’ouverture d’un fichier n’est pas un succès, fopen retourne NULL.

Page 8: Fichiers séquentiels - Université Laval

8

Écriture dans un fichierDès qu’un fichier est ouvert en écriture, nous pouvons écrire dans ce fichierà n’importe quel moment en autant que le pointeur de fichier est disponible.

Opération d’écriture la plus simple : fputc

Écriture d’un caractère représenté par c dans un fichier décrit par pFichier.

int fputc(int c, FILE * pFichier);

Si l’opération d’écriture est réussie, fputc retourne le caractère c;autrement, le caractère spécial EOF défini dans <stdio.h> est retourné.

Opération de lecture la plus simple : fgetc

Lecture d’un caractère dans un fichier décrit par pFichier.int fgetc(FILE * pFichier);

Si l’opération de lecture est réussie, fgetc retourne le caractère lu commeune valeur de type int; autrement, le caractère spécial EOF est retourné.

Note : La fonction fflush permet d’écrire les données de la mémoire tampondans le fichier et de vider ce bloc de mémoire.

int fflush(FILE * pFichier); // Retourne EOF s’il y a erreur.

Page 9: Fichiers séquentiels - Université Laval

9

Gestion d’un fichier - exemple#include <stdio.h>#include <string.h>

void main(){

char chaine[80];int i;int c;

// Création d'un fichier.

FILE * pFichier = NULL;

pFichier = fopen("E:\\Nouveau_dossier\\Essai.txt", "w");

// Saisie au clavier d'une chaîne de caractères.

printf("Entrez une chaine de caracteres :");scanf("%s", &chaine);

Page 10: Fichiers séquentiels - Université Laval

10

Gestion d’un fichier - exemple// Écrire dans le fichier la chaîne de caractères inversée.

for (i = strlen(chaine) - 1; i >= 0; i--)fputc(chaine[i], pFichier);

fclose(pFichier); // Fermeture du fichier ouvert en écriture.

// Ouverture d'un fichier en lecture.

pFichier = fopen("E:\\Nouveau_dossier\\Essai.txt", "r");

// Lecture de chaque caractère du fichier et affichage à l'écran.

c = fgetc(pFichier);while (c != EOF){

printf("%c", c);c = fgetc(pFichier);

}printf("\n");

Page 11: Fichiers séquentiels - Université Laval

11

Gestion d’un fichier - exemplefclose(pFichier); // Fermeture du fichier ouvert en lecture.

// Le fichier créé est supprimé.

remove("E:\\Nouveau_dossier\\Essai.txt");} Ne pas utiliser

pFichier.

Page 12: Fichiers séquentiels - Université Laval

12

Lire et écrire une chaîne de caractères dans un fichierOpération d’écriture : fputs

Écriture d’une chaîne pointée par pChaine dans un fichier décrit par pFichier.

int fputs(char * pChaine, FILE * pFichier);

La copie s’effectue jusqu’à ce que l’on rencontre le caractère '\0'.Ce dernier n’est pas copié dans le fichier; cela peut compliquer la lecturedu fichier par la suite.

Si l’opération d’écriture n’est pas réussie, fputs retourne le caractère EOF.

Opération d’écriture : fgets

Lecture des Nb_de_caracteres -1 prochains caractères d’un fichier décritpar pFichier pour les ranger dans une chaîne pointée par pChaine .

char * fgets(char * pChaine, int Nb_de_caracteres, FILE * pFichier);

Page 13: Fichiers séquentiels - Université Laval

13

Lire et écrire une chaîne de caractères dans un fichier#include <stdio.h>void main(){

char chaine[5]; char Fin;

// Création d'un fichier.FILE * pFichier = fopen("E:\\Nouveau_dossier\\Essai.txt", "w");

printf("Desirez-vous poursuivre (O ou N) ?"); scanf("%c", &Fin);while (Fin == 'O'){

// Saisie au clavier d'un nom.printf("Entrez un nom : "); scanf("%s", chaine);

// Écrire le nom dans le fichier.fputs(chaine, pFichier);

printf("Desirez-vous poursuivre (O ou N) ?");scanf("\n%c", &Fin);

}

Page 14: Fichiers séquentiels - Université Laval

14

Lire et écrire une chaîne de caractères dans un fichierfclose(pFichier); // Fermeture du fichier ouvert en écriture.

// Ouverture d'un fichier en lecture.

pFichier = fopen("E:\\Nouveau_dossier\\Essai.txt", "r");

// Lecture de chaque nom du fichier et affichage à l'écran.

while(fgets(chaine, 5, pFichier) != NULL)printf("\n%s", chaine);

fclose(pFichier); // Fermeture du fichier ouvert en lecture.

// Le fichier créé est supprimé.

remove("E:\\Nouveau_dossier\\Essai.txt");}

Page 15: Fichiers séquentiels - Université Laval

15

Lire et écrire dans un fichier formatéOpération d’écriture : fprintf Semblable à printf.

fprintf(pFichier, "%12d\n%12d\n%14f\n", int1, int2, reel1);Ex. :

pFichier a besoin d’être initialisé à l’aide de fopen() en premier.

Note : Il faut ajouter le symbole de fin de ligne '\n' pour séparer les données.

Opération de lecture : fscanf Semblable à scanf.

fscanf(pFichier, "%12d\n%12d\n%14f\n", &int1, &int2, &reel1);Ex. :

Retourne EOF si une erreur est commise; le nombre de données luesautrement.

Note : Il faut ajouter le symbole de fin de ligne '\n' parce que les données sont séparées.

Page 16: Fichiers séquentiels - Université Laval

16

Lire et écrire dans un fichier formaté - exemple#include <stdio.h>

void main(){

FILE * pFichier;

char Nom_Fichier[30], Nom_Etudiant[25], Prenom_Etudiant[25];

int matricule;

int Nb_d_enregistrements = 0, Nombre_d_enregistrements;

// Ouverture du fichier en écriture.

printf("Entrez le nom du fichier : ");scanf("%s", Nom_Fichier);

pFichier = fopen(Nom_Fichier, "w");

Page 17: Fichiers séquentiels - Université Laval

17

Lire et écrire dans un fichier formaté - exemple// Écriture dans le fichier.printf("Nombre d'enregistrements a inserer : ");scanf("%d", &Nombre_d_enregistrements);

while (Nb_d_enregistrements < Nombre_d_enregistrements){

printf("Entrez le nom de l'etudiant : ");scanf("%s", Nom_Etudiant);printf("Entrez le prenom de l'etudiant : ");scanf("%s", Prenom_Etudiant);printf("Entrez le matricule de l'etudiant : ");scanf("%6d", &matricule);

fprintf(pFichier, "%s\n%s\n%6d\n",Nom_Etudiant, Prenom_Etudiant, matricule);

Nb_d_enregistrements += 1;}// Fermeture du fichier.fclose(pFichier);

Page 18: Fichiers séquentiels - Université Laval

18

Lire et écrire dans un fichier formaté - exemple// Ouverture du fichier en lecture.pFichier = fopen(Nom_Fichier, "r");

// Lecture et affichage du contenu du fichier.while(! feof(pFichier)){

fscanf(pFichier, "%s\n%s\n%6d\n",Nom_Etudiant, Prenom_Etudiant, &matricule);

printf("%s %s %6d\n",Nom_Etudiant, Prenom_Etudiant, matricule);

}rewind(pFichier);while(! feof(pFichier)) // Détection de la fin du fichier.{

fscanf(pFichier, "%s\n%s\n%6d\n",Nom_Etudiant, Prenom_Etudiant, &matricule);

printf("Nom : %s Prenom : %s Matricule : %6d\n",Nom_Etudiant, Prenom_Etudiant, matricule);

}

Page 19: Fichiers séquentiels - Université Laval

19

Lire et écrire dans un fichier formaté - exemple// Fermeture du fichier.

fclose(pFichier);

// Détruire le fichier.

remove(Nom_Fichier);}

Page 20: Fichiers séquentiels - Université Laval

20

Supprimer un enregistrement dans un fichierLe nouveau fichier est créé en copiant chaque enregistrement de l’ancien fichierqui précède l’enregistrement à supprimer et tous ceux qui le suivent.

Dans le cas où l’on veut modifier un enregistrement dans un fichier, on procèdede la même façon à l’exception que l’enregistrement modifié est copié.

Page 21: Fichiers séquentiels - Université Laval

21

Supprimer un enregistrement dans un fichier - exemple

#include <stdio.h>

void main(){

FILE * pFichier_ancien;FILE * pFichier_nouveau;

char Nom_Fichier_ancien[30], Nom_Fichier_nouveau[30],Nom_Etudiant[25], Prenom_Etudiant[25];

int matricule;

int Nb_d_enregistrements = 0, Nombre_d_enregistrements;

// Ouverture du fichier en écriture.

printf("Entrez le nom du fichier : ");scanf("%s", Nom_Fichier_ancien);

pFichier_ancien = fopen(Nom_Fichier_ancien, "w");

Page 22: Fichiers séquentiels - Université Laval

22

Supprimer un enregistrement dans un fichier - exemple

// Écriture dans le fichier.

printf("Nombre d'enregistrements a inserer : ");scanf("%d", &Nombre_d_enregistrements);

while (Nb_d_enregistrements < Nombre_d_enregistrements){

printf("Entrez le nom de l'etudiant : ");scanf("%s", Nom_Etudiant);printf("Entrez le prenom de l'etudiant : ");scanf("%s", Prenom_Etudiant);printf("Entrez le matricule de l'etudiant : ");scanf("%6d", &matricule);

fprintf(pFichier_ancien, "%s\n%s\n%6d\n",Nom_Etudiant, Prenom_Etudiant, matricule);

Nb_d_enregistrements += 1;}

Page 23: Fichiers séquentiels - Université Laval

23

Supprimer un enregistrement dans un fichier - exemple

// Fermeture de l'ancien fichier.fclose(pFichier_ancien);

// Ouverture du fichier en lecture.

pFichier_ancien = fopen(Nom_Fichier_ancien, "r");

// Lecture et affichage du contenu du fichier.

while(! feof(pFichier_ancien)){

fscanf(pFichier_ancien, "%s\n%s\n%6d\n",Nom_Etudiant, Prenom_Etudiant, &matricule);

printf("%s %s %6d\n",Nom_Etudiant, Prenom_Etudiant, matricule);

}

// On se repositionne au début du fichier.rewind(pFichier_ancien);

Page 24: Fichiers séquentiels - Université Laval

24

Supprimer un enregistrement dans un fichier - exemple

// Ouverture en écriture du nouveau fichier.printf("Entrez le nom du nouveau fichier : ");scanf("%s", Nom_Fichier_nouveau);

pFichier_nouveau = fopen(Nom_Fichier_nouveau, "w");

// Construction du nouveau fichier à partir de l'ancien.

while(! feof(pFichier_ancien)){

fscanf(pFichier_ancien, "%s\n%s\n%6d\n",Nom_Etudiant, Prenom_Etudiant, &matricule);

if (matricule != 123456)fprintf(pFichier_nouveau, "%s\n%s\n%6d\n",Nom_Etudiant, Prenom_Etudiant, matricule);

}

// Fermeture et destruction de l'ancien fichier.fclose(pFichier_ancien);remove(Nom_Fichier_ancien);

Page 25: Fichiers séquentiels - Université Laval

25

Supprimer un enregistrement dans un fichier - exemple

// Fermeture du nouveau fichier.fclose(pFichier_nouveau);

// Ouverture du nouveau fichier en lecture.pFichier_nouveau = fopen(Nom_Fichier_nouveau, "r");

// Lecture et affichage du contenu du nouveau fichier.

while(! feof(pFichier_nouveau)){

fscanf(pFichier_nouveau, "%s\n%s\n%6d\n",Nom_Etudiant, Prenom_Etudiant, &matricule);

printf("%s %s %6d\n",Nom_Etudiant, Prenom_Etudiant, matricule);

}

// Fermeture et destruction du nouveau fichier.fclose(pFichier_nouveau);remove(Nom_Fichier_nouveau);

}

Page 26: Fichiers séquentiels - Université Laval

26

Fichiers temporaires

Dans une application, si vous avez besoin d’un fichier pour la durée duprogramme seulement, vous pouvez créer un fichier temporaire :

FILE * pNom_du_fichier = tmpfile();

Retourne un pointeur au fichier temporaire.

Aucune ouverture de fichier; on peut écrire ou lire dans le fichier.

Par contre, le fichier est détruit dès qu’il est fermé. On ne peut pas effectuerla séquence suivante :

- ouverture en écriture,- insertion dans le fichier,- fermeture du fichier,- ouverture en lecture,- accès en lecture.

Page 27: Fichiers séquentiels - Université Laval

Calcul du ke élément d’une suite de n éléments distincts

27

Exemple : Trouver le kième plus petit entier dans une suite d'entiers distinctsde longueur n sans trier la suite. La valeur de k est entre 1 et n.

20 18 24 2 35 9 10 8 4 0 36k = 3

2018 2 9 10 8 4 0 24 35 3618 2 9 10 8 4 0k = 3

182 9 10 8 4 0

2 9 10 8 4 0k = 3

20 9 10 8 4

k = 1 9 10 8 4

98 4 10

8 4k = 1

84

k = 1 4 Rép. : 4

Page 28: Fichiers séquentiels - Université Laval

28

Fichiers temporaires - Exemple#include <stdio.h>

void main(){

// Trouver le k ième plus petit entier dans une suite d'entiers distincts// de longueur n sans trier la suite.// La valeur de k est entre 1 et n.

enum bool {false = 0, true = 1};FILE * pFichier = tmpfile();FILE * pTempA; FILE * pTempB;int longA, longB;

int k, n;int Nb_enreg = 0;int un_element;int pivot;enum bool inacheve = true;

Page 29: Fichiers séquentiels - Université Laval

29

Fichiers temporaires - Exemple// Saisie des valeurs de k et de n.

printf("Entrez les valeurs de k et n : ");scanf("%d%d", &k, &n);

// Saisie des n entiers de la suite et stockage dans le fichier pFichier.

while (Nb_enreg < n){

printf("Entrez une valeur entiere de la suite : ");scanf("%d", &un_element);

fprintf(pFichier, "%d\n", un_element);Nb_enreg += 1;

}

Page 30: Fichiers séquentiels - Université Laval

30

Fichiers temporaires - Exemplewhile (inacheve){

// On se positionne au début du fichier qui renferme la suite.

rewind(pFichier);

// Deux fichiers temporaires vides sont créés.

pTempA = tmpfile();pTempB = tmpfile();

// Le premier élément de la suite est choisi comme pivot.

fscanf(pFichier, "%d\n", &pivot);

// Placer tous les autres éléments <= pivot dans pTempA.// Placer tous les autres éléments > pivot dans pTempB.

Page 31: Fichiers séquentiels - Université Laval

31

Fichiers temporaires - ExemplelongA = longB = 0;while (!feof(pFichier)){

fscanf(pFichier, "%d\n", &un_element);if (un_element <= pivot){

fprintf(pTempA, "%d\n", un_element);longA += 1;

}else{

fprintf(pTempB, "%d\n", un_element);longB += 1;

}}

Page 32: Fichiers séquentiels - Université Laval

32

Fichiers temporaires - Exemple// Si le fichier pTempA renferme k-1 éléments, cela signifie// que le pivot est le k ième plus petit élément recherché.// C'est terminé.

if (longA == k-1){

printf("%d", pivot); inacheve = false;} else

// Si le fichier pTempA renferme k éléments ou plus, cela signifie// que le pivot est dans le fichier pTempA.// On détruit le fichier pTempB et on fait pointer pFichier vers pTempA.// Le problème consiste maintenant à calculer le k ième plus petit// élément dans le nouveau fichier pointé par pFichier.

if (longA >= k){

fclose(pTempB);pFichier = pTempA;

}

Page 33: Fichiers séquentiels - Université Laval

33

Fichiers temporaires - Exempleelse // longA < k - 1.

// Si le fichier pTempA renferme au plus k - 2 éléments, cela// signifie que le pivot est dans le fichier pTempB.

// On détruit le fichier pTempA et on fait pointer pFichier vers// pTempB.

// Le problème consiste maintenant à calculer le k - longA – 1// ième plus petit élément dans le nouveau fichier pointé par// pFichier.

{k = k - longA - 1;fclose(pTempA);pFichier = pTempB;

}

}}