sommaire du chapitre :
3. Accès aux fichiers séquentiels
3a. Le type FILE*
3b. Exemple: Créer et afficher un fichier séquentiel4. Ouvrir et fermer des fichiers séquentiels
4a. Ouvrir un fichier séquentiel
4b. Fermer un fichier séquentiel
4c. Exemples: Ouvrir et fermer des fichiers en pratique5. Lire et écrire dans des fichiers séquentiels
5a. Traitement par enregistrements
5b. Traitement par caractères
5c. Détection de la fin d'un fichier séquentiel7. Mise à jour d'un fichier séquentiel en C
7a. Ajouter un enregistrement à un fichier
7b. Supprimer un enregistrement dans un fichier
7c. Modifier un enregistrement dans un fichier
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,
(le clavier) et ils ont écrit leurs résultats dans le fichier de sortie standard
(l'écran).
Nous allons voir dans ce chapitre, comment nous pouvons créer, lire et modifier
nous-mêmes des fichiers sur les périphériques disponibles.
Fichier
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, ...).
Un fichier structuré contient une suite d'enregistrements homogènes, qui regroupent
le plus souvent plusieurs composantes appartenant ensemble (champs).
Fichier séquentiel
Dans des fichiers séquentiels, les enregistrements sont mémorisés consécutivement
dans l'ordre de leur entrée et peuvent seulement être lus dans cet ordre.
Si on a besoin d'un enregistrement précis dans un fichier séquentiel, il faut
lire tous les enregistrements qui le précèdent, en commençant par le premier.
En simplifiant, nous pouvons nous imaginer qu'un fichier séquentiel est enregistré sur une bande magnétique.
Propriétés
Les fichiers séquentiels que nous allons considérer dans ce cours auront les
propriétés suivantes :
-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.
-A un moment donné, on peut uniquement accéder à un seul enregistrement; celui
qui se trouve en face de la tête de lecture/écriture.
-Après chaque accès, la tête de lecture/écriture est déplacée derrière la donnée
lue en dernier lieu.
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,
soit les programmes lisent leurs données au clavier et écrivent les résultats
sur l'écran.
Exemple :
L'appel suivant du programme PROG lit les données dans le fichier C:\TEST.TXT
au lieu du clavier et écrit les résultats sur l'imprimante au lieu de l'écran.
PROG <C:\TEST.TXT>PRN:
En fait, l'affectation de stdin et stdout est gérée par le système d'exploitation;
ainsi le programme ne 'sait' pas d'où viennent les données et où elles vont.
Pour des raisons d'efficacité, les accès à un fichier se font
par l'intermédiaire d'une mémoire tampon.
La mémoire tampon est une zone de la mémoire centrale de la machine réservée
à un ou plusieurs enregistrements du fichier.
L'utilisation de la mémoire tampon a l'effet de réduire le nombre d'accès à
la périphérie d'une part et le nombre des mouvements de la tête de lecture/écriture
d'autre part.
3. Accès aux fichiers séquentiels
Les problèmes traitant des fichiers ont généralement la forme
suivante : un fichier donné par son nom (et en cas de besoin le chemin d'accès
sur le médium de stockage) doit être créé, lu ou modifié.
La question qui se pose est alors :
Comment pouvons-nous relier le nom d'un fichier sur un support externe avec les instructions qui donnent accès au contenu du fichier ?
En résumé, la méthode employée sera la suivante :
Avant de lire ou d'écrire un fichier, l'accès est notifié par
la commande fopen.
fopen accepte le nom du fichier (ex : "A:\ADRESSES.DAT"), négocie avec
le système d'exploitation et fournit un pointeur spécial qui sera utilisé ensuite
lors de l'écriture ou la lecture du fichier.
Après les traitements, il faut annuler la liaison entre le nom du fichier et
le pointeur à l'aide de la commande fclose.
On peut dire aussi qu'entre les événements fopen() et fclose() le fichier est ouvert.
Pour pouvoir travailler avec un fichier, un programme a besoin
d'un certain nombre d'informations au sujet du fichier:
- adresse de la mémoire tampon
- position actuelle de la tête de lecture/écriture
- type d'accès au fichier: écriture, lecture, ...
- état d'erreur
- ...
Ces informations (dont nous n'aurons pas à nous occuper), sont
rassemblées dans une structure du type spécial FILE.
Lorsque nous ouvrons un fichier avec la commande fopen, le système génère
automatiquement un bloc du type FILE et nous fournit son adresse.
Tout ce que nous avons à faire dans notre programme est :
-déclarer un pointeur du type FILE * pour chaque fichier dont nous avons besoin
-affecter l'adresse retournée par fopen à ce pointeur
-employer le pointeur à la place du nom du fichier dans toutes les instructions
de lecture ou d'écriture
-libérer le pointeur à la fin du traitement à l'aide de fclose
3b. Exemple: Créer et afficher un fichier séquentiel
Avant de discuter les détails du traitement des fichiers, nous vous présentons un petit exemple comparatif qui réunit les opérations les plus importantes sur les fichiers.
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 ou
sur disquette.
Après avoir écrit et fermé le fichier, le programme va rouvrir 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 algorithmique
Programme PERSONNEL
chaine NOM_FICHIER , NOM_PERSO
entier C, NB_ENREG
(* Premiere partie : créer et remplir le fichier *)
écrire "Entrez le nom de fichier à créer : "
lire NOM_FICHIER
ouvrir NOM_FICHIER en écriture
écrire "Nombre d'enregistrements à créer
: "
lire NB_ENREG
en C ranger 0
TantQue (C < NB_ENREG) Faire
écrire "Entrez le nom de la presonne : "
lire NOM_PERSO
écrire NOM_FICHIER : NOM_PERSO
en C ranger C+1
FinTantQue
fermer NOM_FICHIER
(* Deuxieme partie : Lire et afficher le contenu du fichier *)
ouvrir NOM_FICHIER en lecture
en C ranger 0
TantQue non(FinFichier(NOM_FICHIER)) Faire
lire NOM_FICHIER:NOM_PERSO
écrire "NOM : ",NOM_PERSO
en C ranger C+1
FinTantQue
fermer NOM_FICHIER
FinProgramme
Solution en langage C
#include
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");
/* w pour 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");
/* r pour read */
C = 0;
while (!feof(P_FICHIER))
{
fscanf(P_FICHIER, "%s\n", NOM_PERS);
printf("NOM : %s\n", NOM_PERS);
C++;
}
fclose(P_FICHIER);
return 0;
}
4. Ouvrir et fermer des fichiers séquentiels
Avant de créer ou de lire un fichier, nous devons informer le
système de cette intention pour qu'il puisse réserver la mémoire pour la zone
d'échange et initialiser les informations nécessaires à l'accès du fichier.
Nous parlons alors de l'ouverture d'un fichier.
Après avoir terminé la manipulation du fichier, nous devons vider
la mémoire tampon et libérer l'espace en mémoire que nous avons occupé pendant
le traitement.
Nous parlons alors de la fermeture du fichier.
L'ouverture et la fermeture de fichiers se font à l'aide des fonctions
fopen et fclose définies dans la bibliothèque standard
4a. Ouvrir un fichier séquentiel
Ouvrir un fichier en langage algorithmique
ouvrir
ou bien
ouvrir
<NomFichier> est une chaîne de caractères constante ou une variable de
type chaîne qui représente le nom du fichier sur le médium de stockage.
Ouvrir un fichier en C - fopen
Lors de l'ouverture d'un fichier avec fopen, le système
s'occupe de la réservation de la mémoire tampon dans la mémoire centrale et
génère les informations pour un nouvel élément du type FILE.
L'adresse de ce bloc est retournée comme résultat si l'ouverture s'est déroulée
avec succès.
La commande fopen peut ouvrir des fichiers en écriture ou en lecture
en dépendance de son deuxième paramètre ("r" ou "w") :
ou bien
<PointeurVersFile> = fopen (<NomFichier>
-<NomFichier> est une chaîne de caractères constante ou
une variable de type chaîne qui représente le nom du fichier sur le médium de
stockage
-le deuxième argument détermine le mode d'accès au fichier :
"w" pour "ouverture en écriture" - write -
"r" pour "ouverture en lecture" - read -
<PointeurVersFile> est un pointeur du type FILE* qui sera
relié au fichier sur le médium de stockage.
Dans la suite du programme, il faut utiliser
<PointeurVersFile> doit être déclaré comme: FILE *FP
Le résultat de fopen
Si le fichier a pu être ouvert avec succès, fopen fournit
l'adresse d'un nouveau bloc du type FILE.
En général, la valeur de cette adresse ne nous intéresse pas; elle est simplement
affectée à un pointeur
A l'apparition d'une erreur lors de l'ouverture du fichier, fopen fournit la valeur numérique zéro qui est souvent utilisée dans une expression conditionnelle pour assurer que le traitement ne continue pas avec un fichier non ouvert.
Ouverture en écriture
Dans le cas de la création d'un nouveau fichier, le nom du fichier est ajouté au répertoire du médium de stockage et la tête de lecture/écriture est positionnée sur un espace libre du médium.
Si un fichier existant est ouvert en écriture, alors son contenu est perdu.
Si un fichier non existant est ouvert en écriture, alors il est
créé automatiquement.
Si la création du fichier est impossible alors fopen indique une erreur
en retournant la valeur zéro.
Autres possibilités d'erreurs signalées par un résultat nul :
- chemin d'accès non valide
- pas de disque/bande dans le lecteur
- essai d'écrire sur un médium protégé contre l'écriture
- ...
Ouverture en lecture
Dans le cas de la lecture d'un fichier existant, le nom du fichier doit être retrouvé dans le répertoire du médium et la tête de lecture/écriture est placée sur le premier enregistrement de ce fichier.
Possibilités d'erreurs signalées par un résultat nul :
- essai d'ouvrir un fichier non existant
- essai d'ouvrir un fichier sans autorisation d'accès
- essai d'ouvrir un fichier protégé contre la lecture
- ...
Remarque avancée :
Si un fichier n'a pas pu être ouvert avec succès, (résultat NULL), un code d'erreur
est placé dans la variable errno.
Ce code désigne plus exactement la nature de l'erreur survenue. Les codes d'erreurs
sont définis dans
- L'appel de la fonction strerror(errno) retourne un pointeur
sur la chaîne de caractères qui décrit l'erreur dans errno.
- L'appel de la fonction perror(s) affiche la chaîne s et le message
d'erreur qui est défini pour l'erreur dans errno.
4b. Fermer un fichier séquentiel
Fermer un fichier en langage algorithmique
f ermer <NomFichier>
<NomFichier> est une chaîne de caractères constante ou une variable de type chaîne qui représente le nom du fichier que l'on désire fermer.
Fermer un fichier en langage C
fclose(<PointeurVersFile>);
<PointeurVersFile> est un pointeur du type FILE* relié au nom du fichier que l'on désire fermer.
La fonction fclose provoque le contraire de fopen :
Si le fichier a été ouvert en écriture, alors les données non écrites de la mémoire tampon sont écrites et les données supplémentaires (longueur du fichier, date et heure de sa création) sont ajoutées dans le répertoire du médium de stockage.
Si le fichier a été ouvert en lecture, alors les données non lues de la mémoire tampon sont simplement "jetées".
La mémoire tampon est ensuite libérée et la liaison entre le pointeur sur FILE et le nom du fichier correspondant est annulée.
Après fclose() le pointeur
Des erreurs graves pourraient donc survenir si ce pointeur est utilisé par la
suite !
5. Lire et écrire dans des fichiers séquentiels
Les fichiers que nous employons dans ce manuel sont des fichiers
texte, ie : toutes les informations dans les fichiers sont mémorisées sous forme
de chaînes de caractères et sont organisées en lignes.
Même les valeurs numériques (types int, float, double,
...) sont stockées comme chaînes de caractères.
Pour l'écriture et la lecture des fichiers, nous allons utiliser les fonctions standard fprintf, fscanf, fputc et fgetc qui correspondent à printf, scanf, putchar et getchar si nous indiquons stdout respectivement stdin comme fichiers de sortie ou d'entrée.
5a. Traitement par enregistrements
Les fichiers texte sont généralement organisés en lignes, la fin d'une information dans le fichier est marquée par le symbole "\n".
ATTENTION ! :
Pour pouvoir lire correctement les enregistrements dans un fichier séquentiel,
le programmeur doit connaître l'ordre des différentes rubriques (champs) à l'intérieur
des enregistrements.
Ecrire une information dans un fichier séquentiel
Ecrire dans un fichier séquentiel en langage algorithmique
écrire <NomFichier>:<Expression1>
écrire <NomFichier>:<Expression2>
...
écrire <NomFichier>:<ExpressionN>
-<NomFichier> est une chaîne de caractères constante ou
une variable de type chaîne qui représente le nom du fichier dans lequel on
veut écrire.
-<ExpressionN> représentent les rubriques qui forment un enregistrement
et dont les valeurs respectives sont écrites dans le fichier.
Ecrire dans un fichier séquentiel en langage C - fprintf
fprintf(<PointeurVersFile> , "<SpecificateurFormat1>
fprintf(<PointeurVersFile> , "<SpecificateurFormat2>
...
fprintf(<PointeurVersFile> , "<SpecificateurFormatN>
ou bien
fprintf(<PointeurVersFile> , "<SpecificateurFormat1>
\n <SpecificateurFormat2> \n ... <SpecificateurFormatN>
-<PointeurVersFile> est un pointeur du type FILE* qui est
relié au nom du fichier cible.
-<Expression1>),<Expression2>),...,<ExpressionN> représentent
les rubriques qui forment un enregistrement et dont les valeurs respectives
sont écrites dans le fichier.
-<SpecificateurFormat1>,<SpecificateurFormat2>,...,<SpecificateurFormatN>
représentent les spécificateurs de format pour l'écriture des différentes rubriques.
Remarque :
L'instruction
fprintf(stdout, "Bonjour\n");
est identique à
printf("\Bonjour \n");
ATTENTION !
Notez que fprintf (et printf) écrit toutes les chaînes de caractères
sans le symbole de fin de chaîne "\0".
Dans les fichiers texte, il faut ajouter le symbole de fin de ligne "\n"
pour séparer les données.
Lire une information dans un fichier séquentiel
Lire dans un fichier séquentiel en langage algorithmique
lire <NomFichier>:<Variable1>
lire <NomFichier>:<Variable2>
...
lire <NomFichier>:<VariableN>
-<NomFichier> est une chaîne de caractères constante ou
une variable de type chaîne qui représente le nom du fichier duquel on veut
lire.
-<Variable1>, <Variable2>, ..., <VariableN> représentent les
variables qui vont recevoir les valeurs des différentes rubriques d'un enregistrement
lu dans le fichier.
Lire dans un fichier séquentiel en langage C - fscanf
fscanf(<PointeurVersFile> , "<SpecificateurFormat1>
fscanf(<PointeurVersFile> , "<SpecificateurFormat2>
...
fscanf(<PointeurVersFile> , "<SpecificateurFormatN>
ou bien
fprintf(<PointeurVersFile> , "<SpecificateurFormat1>
\n <SpecificateurFormat2> \n ... <SpecificateurFormatN>
-<PointeurVersFile> est un pointeur du type FILE* qui est
relié au nom du fichier à lire.
-<AdrVariable1> , <AdrVariable2> , ... , <AdrVariableN> représentent
les adresses des variables qui vont recevoir les valeurs des différentes rubriques
d'un enregistrement lu dans le fichier.
-<SpecificateurFormat1>,<SpecificateurFormat2>,...,<SpecificateurFormatN>
représentent les spécificateurs de format pour l'écriture des différentes rubriques.
Remarque :
L'instruction
fscanf(stdin, "%d \n", &N);
est identique à
scanf("%d \n", &N);
ATTENTION !
Pour les fonctions scanf et fscanf tous les signes d'espacement
sont équivalents comme séparateurs.
En conséquence, à l'aide de fscanf, il nous sera impossible de lire toute
une phrase dans laquelle les mots sont séparés par des espaces.
La manipulation de fichiers avec les instructions fprintf
et fscanf n'est pas assez flexible pour manipuler de façon confortable
des textes écrits.
Il est alors avantageux de traiter le fichier séquentiellement caractère par
caractère.
Ecrire un caractère dans un fichier séquentiel - fputc
fputc(<Caractere>
fputc transfère le caractère indiqué par
-<Caractere> représente un caractère (valeur numérique de
0 à 255) ou le symbole de fin de fichier EOF.
-<PointeurVersFile> est un pointeur du type FILE* qui est relié au nom
du fichier cible.
Remarque :
L'instruction
fputc("a", stdout);
est identique à
putchar("a");
Lire un caractère dans un fichier séquentiel - fgetc
fgetc fournit comme résultat le prochain caractère du fichier
référencé par
A la fin du fichier, fgets retourne EOF.
-<Caractere> représente une variable du type int
qui peut accepter une valeur numérique de 0 à 255 ou le symbole de fin de fichier
EOF.
-<PointeurVersFile> est un pointeur du type FILE* qui est relié au nom
du fichier à lire.
Remarque :
L'instruction
C = fgetc(stdin);
est identique à
C = getchar();
5c. Détection de la fin d'un fichier séquentiel
Lors de la fermeture d'un fichier ouvert en écriture, la fin du
fichier est marquée automatiquement par le symbole de fin de fichier EOF
(End Of File).
Lors de la lecture d'un fichier, les fonctions finfichier(
Détection de la fin d'un fichier en langage algorithmique
finfichier(
finfichier retourne la valeur logique vrai, si la tête de lecture
du fichier référencé par
Détection de la fin d'un fichier en langage C - feof
feof(
feof retourne une valeur différente de zéro, si la tête
de lecture du fichier référencé par
Pour que la fonction feof détecte correctement la fin du fichier,
il faut qu'après la lecture de la dernière donnée du fichier, la tête de lecture
arrive jusqu'à la position de la marque EOF.
Nous obtenons cet effet seulement si nous terminons aussi la chaîne de format
de fscanf par un retour à la ligne "\n" (ou par un autre signe
d'espacement).
Exemples :
Une boucle de lecture typique pour lire les enregistrements d'un fichier séquentiel
référencé par un pointeur <PointeurVersFile> peut avoir la forme suivante
:
while (!feof(<PointeurVersFile>))
{
fscanf(<pointeurVersFile>, "%s\n ... \n", NOM, ...
); ...
}
Le programme suivant lit et affiche le fichier "C:\AUTOEXEC.BAT"
en le parcourant caractère par caractère:
#include
#include
main()
{
FILE *FP;
FP = fopen("C:\\AUTOEXEC.BAT", "r");
if (!FP)
{ printf("Impossible d'ouvrir le fichier\n"); exit(-1);
}
while (!feof(FP))
{ putchar(fgetc(FP)); }
fclose(FP);
return 0;
}
Algorithmique
|
C
|
|
Ouverture en écriture | Ouvrir <Nom> en écriture | <Pointeur> = fopen(<Nom>,"w"); |
Ouverture en lecture | Ouvrir <Nom> en lecture | <Pointeur> = fopen(<Nom>,"r"); |
Fermeture | Fermer <Nom> | fclose(<Pointeur>); |
Fonction Fin Fichier | FinFichier(<Nom>) | feof(<Pointeur>); |
Ecriture | ecrire <Nom>:<Expression> |
fprint(<Pointeur>,"...",<AdresseDansFile>); |
Lecture | lire <Nom>:<Variable> | fscanf(<Pointeur>,"...",<AdresseDansFile>); <Caractere> = fgetc (<Pointeur>); |
7. Mise à jour d'un fichier séquentiel en C
Dans ce chapitre, nous allons résoudre les problèmes standards
sur les fichiers, à savoir :
- l'ajout d'un enregistrement à un fichier
- la suppression d'un enregistrement dans un fichier
- la modification d'un enregistrement dans un fichier
Comme il est impossible de lire et d'écrire en même temps dans
un fichier séquentiel, les modifications doivent se faire à l'aide d'un fichier
supplémentaire.
Nous travaillons donc typiquement avec au moins deux fichiers : l'ancien fichier
ouvert en lecture et le nouveau fichier ouvert en écriture.
7a. Ajouter un enregistrement a un fichier
Nous pouvons ajouter le nouvel enregistrement à différentes positions dans le fichier :
Ajout d'un enregistrement à la fin d'un fichier
L'ancien fichier est entièrement copié dans le nouveau fichier, suivi du nouvel enregistrement.
Ajout d'un enregistrement au début d'un fichier
L'ancien fichier est copié derrière le nouvel enregistrement qui est écrit en premier lieu.
Insertion dans un fichier trié relativement à une rubrique commune des enregistrements
Le nouveau fichier est créé en trois étapes :
- copier les enregistrements de l'ancien fichier qui précèdent le nouvel enregistrement
- écrire le nouvel enregistrement
- copier le reste des enregistrements de l'ancien fichier
Exemple :
Le programme suivant effectue l'insertion d'un enregistrement
à introduire au clavier dans un fichier trié selon la seule rubrique de ses
enregistrements: le nom d'une personne.
Le programme inclut en même temps les solutions aux deux problèmes précédents.
La comparaison lexicographique des noms des personnes se fait à l'aide de
la fonction strcmp.
#include
#include
main()
{
/* Déclarations : */
/* Noms des fichiers et pointeurs de référence */
char ANCIEN[30], NOUVEAU[30]; FILE *INFILE, *OUTFILE;
/* Autres variables */
char NOM_PERS[30], NOM_AJOUT[30];
int TROUVE;
/* Ouverture de l'ancien fichier en lecture */
do
{
printf("Nom de l'ancien fichier : ");
scanf("%s", ANCIEN);
INFILE = fopen(ANCIEN, "r");
if (!INFILE) { printf("\aERREUR: Impossible d'ouvrir
le fichier: %s.\n", ANCIEN); }
}
while (!INFILE);
/* Ouverture du nouveau fichier en écriture */
do
{
printf("Nom du nouveau fichier : ");
scanf("%s", NOUVEAU);
OUTFILE = fopen(NOUVEAU, "w");
if (!OUTFILE) { printf("\aERREUR: Impossible d'ouvrir
le fichier: %s.\n", NOUVEAU); }
}
while (!OUTFILE);
/* Saisie de l'enregistrement à insérer */
printf("Enregistrement à insérer : ");
scanf("%s",NOM_AJOUT);
/* Traitement */
TROUVE = 0;
/* Copie des enregistrements dont le nom précéde lexicogr. celui à insérer.*/
while (!feof(INFILE) && !TROUVE)
{
fscanf(INFILE, "%s\n", NOM_PERS);
if (strcmp(NOM_PERS, NOM_AJOUT) > 0) { TROUVE = 1; }
else { fprintf(OUTFILE, "%s\n", NOM_PERS); }
}
/* Ecriture du nouvel enregistrement, */
fprintf(OUTFILE, "%s\n", NOM_AJOUT);
/* suivi du dernier enregistrement lu. */
if (TROUVE) { fprintf(OUTFILE, "%s\n", NOM_PERS); }
/* Copie du reste des enregistrements */
while (!feof(INFILE))
{
fscanf(INFILE, "%s\n", NOM_PERS);
fprintf(OUTFILE, "%s\n", NOM_PERS);
}
/* Fermeture des fichiers */
fclose(OUTFILE);
fclose(INFILE);
return 0;
}
7b. Supprimer un enregistrement dans un fichier
Le nouveau fichier est créé en copiant tous les enregistrements de l'ancien fichier qui précèdent l'enregistrement à supprimer et tous ceux qui le suivent
Solution en C
#include
#include
main()
{
/* Déclarations : */
/* Noms des fichiers et pointeurs de référence */
char ANCIEN[30], NOUVEAU[30]; FILE *INFILE, *OUTFILE;
/* Autres variables */
char NOM_PERS[30], NOM_SUPPR[30];
/* Ouverture de l'ancien fichier en lecture */
do
{
printf("Nom de l'ancien fichier : ");
scanf("%s", ANCIEN);
INFILE = fopen(ANCIEN, "r");
if (!INFILE) { printf("\aERREUR: Impossible d'ouvrir
le fichier: %s.\n", ANCIEN); }
}
while (!INFILE);
/* Ouverture du nouveau fichier en écriture */
do
{
printf("Nom du nouveau fichier : ");
scanf("%s", NOUVEAU);
OUTFILE = fopen(NOUVEAU, "w");
if (!OUTFILE) { printf("\aERREUR: Impossible d'ouvrir
" "le fichier: %s.\n", NOUVEAU); }
}
while (!OUTFILE);
/* Saisie de l'enregistrement à supprimer */
printf("Enregistrement à supprimer : ");
scanf("%s",NOM_SUPPR);
/* Traitement */
/* Copie de tous les enregistrements à l'exception de celui à supprimer. */
while (!feof(INFILE))
{
fscanf(INFILE, "%s\n", NOM_PERS);
if (strcmp(NOM_PERS, NOM_SUPPR) != 0) { fprintf(OUTFILE,
"%s\n", NOM_PERS); }
}
/* Fermeture des fichiers */
fclose(OUTFILE);
fclose(INFILE);
return 0;
}
7c. Modifier un enregistrement dans un fichier
Le nouveau fichier est créé de tous les enregistrements de l'ancien fichier qui précèdent l'enregistrement à modifier, de l'enregistrement modifié et de tous les enregistrements qui suivent l'enregistrement à modifier dans l'ancien fichier.
Solution en C
#include
#include
main()
{
/* Déclarations : */
/* Noms des fichiers et pointeurs de référence */
char ANCIEN[30], NOUVEAU[30]; FILE *INFILE, *OUTFILE;
/* Autres variables */
char NOM_PERS[30], NOM_MODIF[30], NOM_NOUV[30];
/* Ouverture de l'ancien fichier en lecture */
do
{
printf("Nom de l'ancien fichier : ");
scanf("%s", ANCIEN);
INFILE = fopen(ANCIEN, "r");
if (!INFILE) { printf("\aERREUR: Impossible d'ouvrir
le fichier: %s.\n", ANCIEN); }
}
while (!INFILE);
/* Ouverture du nouveau fichier en écriture */
do
{
printf("Nom du nouveau fichier : ");
scanf("%s", NOUVEAU);
OUTFILE = fopen(NOUVEAU, "w");
if (!OUTFILE) { printf("\aERREUR: Impossible d'ouvrir
le fichier: %s.\n", NOUVEAU); }
}
while (!OUTFILE);
/* Saisie de l'enregistrement à modifier, */
printf("Enregistrement à modifier : ");
scanf("%s",NOM_MODIF);
/* et de sa nouvelle valeur. */
printf("Enregistrement nouveau : ");
scanf("%s",NOM_NOUV);
/* Traitement */
/* Copie de tous les enregistrements en remplaçant l'enregistrement à modifier
par sa nouvelle valeur. */
while (!feof(INFILE))
{
fscanf(INFILE, "%s\n", NOM_PERS);
if (strcmp(NOM_PERS, NOM_MODIF) = 0) { fprintf(OUTFILE,
"%s\n", NOM_NOUV); }
else { fprintf(OUTFILE, "%s\n", NOM_PERS); }
}
/* Fermeture des fichiers */
fclose(OUTFILE);
fclose(INFILE);
return 0;
}
Conclusion : Un petit mot de l'auteur...
Eh ben voilou... on est a la fin de ce que j'appellerai une
bonne initiation au C...
Maintenant, il ne vous reste plus qu'a mettre ces connaissances en pratique,
et vous pourrez passer au C++ ;)
Bon courage surtout, et ne désespérez pas si cela
vous parait un peu obtus au départ...
Ce langage, avec bien-sur le C++, est de loin le plus efficace...
NiKo