Vous êtes sur la page 1sur 8

VI .

Les Fichiers

Le fichage — la collecte de renseignements — est une pratique qui date de


l'antiquité. Les premières fiches au sens de supports d'informations étaient des
plaquettes gravées par les Babyloniens en 400 av. J.-C.4. À la fin du XIXe siècle, le
terme fiche est (entre autres) défini comme une « feuille de carton sur laquelle on
écrit des titres d'ouvrages, que l'on classe alphabétiquement dans des boîtes, et
auxquelles on recourt pour trouver le volume dans la bibliothèque. On s'en sert
aussi pour préparer des tables de matières. ». De là est plus tard dérivé le terme
fichier, qui désigne un recueil de fiches et, par extension, le meuble destiné à les
contenir.

Au début du XXe siècle, avant l'arrivée des ordinateurs, l'utilisation de fiches


documentaires était courante dans de nombreux domaines. Les informations
étaient consignées sur des feuilles de papier ou de carton, des documents, des
formulaires, des dossiers, rangés dans les tiroirs d'une armoire. C'est en
particulier dans l'administration publique, le commerce et l'industrie que se
trouvaient les plus grands fichiers. L'enregistrement, puis la mise à jour de toutes
les informations contenues sur les documents demandait un effort considérable
et prenait beaucoup de temps. Elle a pu être simplifiée par l'utilisation de cartes
perforées, dont la lecture pouvait être réalisée par des machines.

En 1950, les fichiers informatiques se présentaient sous la forme d'une pile de


cartes perforées, qu'un appareil lisait sans intervention humaine. Elles pouvaient
ainsi être traitées 100 fois plus vite que si les informations avaient été introduites
manuellement. L'organisation des fichiers sur bande magnétique était analogue à
celle des fichiers de carte perforées: ils étaient composés d'enregistrements,
chaque enregistrement correspondant à un ensemble d'informations sur un
même sujet. Depuis 1980, les systèmes d'exploitation tel Unix offrent la possibilité
de stocker de grande quantités d'informations, de les rechercher et de les classer
d'une manière analogue à un bloc-notes dans une hiérarchie où chaque répertoire
peut contenir des fichiers et d'autres répertoires.

Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données
79 80
VII.1 Généralités sur les fichiers bien indique l'endroit courant de la lecture ou de l'écriture dans le fichier. Un concept de
base dans les systèmes d’exploitation de type Unix/Linux est que "tout est un fichier", e.g. le
Les deux opération d'entées/sorties que nous avons traité jusqu'à maintenant prennent les noyaux Linux considère le clavier comme un fichier d’où il peut lire des octets (c’est le pilote
données au clavier et affichent les résultats à l'écran. Ces données sont stockées en mémoire de clavier qui s’occupe de transformer les signaux électriques en flux d’octets). Pour faire
et accessible par ces opérations d'entrées/sorties. Or la mémoire centrale d'un ordinateur est entrer ou sortir des informations, un programme démarre avec trois fichiers (flux standards)
volatile : les informations qui y sont stockées sont détruites à la fin de l'exécution du ouverts : l’entrée standard (stdin), la sortie standard (stdout) et la sortie d’erreurs (stderr).
programme et ne peuvent donc pas être réutilisées ultérieurement. A la fin de l'exécution du Pour accéder à un de ces fichiers/flux, nous pouvons utiliser le descripteur de fichier associé
programme, il n'a plus aucune trace des adresses mémoires dans lesquelles les données du (techniquement un entier, i.e. 0 pour stdin, 1 pour stdout et 2 pour stderr) et les fonctions
programme ont été rangées. Si on l'exécute une deuxième fois, il faut recréer des nouvelles standards pour les entrées/sorties fichiers : read ou write.
données. De plus, lorsqu'un ordinateur est arrêté, toutes les données stockées dans sa
mémoire sont perdues à jamais. On peut distinguer deux grand types de fichiers : les fichiers texte et les fichiers binaires.
Plusieurs types d'information peuvent être conservés dans un fichier : des programmes
D'autres parts, le coût de la mémoire centrale est plus élevé que la mémoire non volatile des exécutables, des images du son, de la vidéo, du texte, etc.
disques durs, bandes magnétiques, CD ou DVD. La taille de la mémoire centrale est par
conséquent très inférieure à la taille de la mémoire non volatile. Pour mémoriser de gros VII.3 Gestion de fichiers
volumes d'information, la mémoire centrale ne suffit pas.
Le système d'exploitation gère une table de descripteurs en mémoire, à chaque fichier est
Ainsi, dans la plupart des applications d'entreprises pour lesquelles un gros volume associé un descripteur correspondant à l'indice dans la table des descripteurs. Trois
d'informations doit être mémorisé plus longtemps que la durée de vie du programme, les descripteurs sont réservés par le système : 0, 1 et 2 correspondants aux pseudo fichiers stdin,
informations sont récupérées et mémorisées sur un support non volatile (disques, disquettes, stdout et stderr. Le flux stdin correspond à l'entrée standard qui est par défaut le clavier ; le
bandes magnétiques…). Les informations y sont enregistrées de manière permanente dans flux stdout correspond au canal standard de sortie (par défaut l'écran) et le flux stderr
des fichiers. correspond à la sortie d'erreurs (elle aussi est par défaut l'écran). Ces trois flux peuvent être
redirigés vers d'autres fichiers.
Les informations ne sont plus seulement communiquées via le clavier et l'écran, mais aussi
via des fichiers de support non volatiles (fig. 27). Il est alors possible qu'un programme ne Pour pouvoir manipuler un fichier, un programme a besoin d’un certain nombre
communique avec son environnement qu'au travers des fichiers et n'utilise ni la saisie, ni d’informations : l’adresse de l’endroit de la mémoire-tampon où se trouve le fichier, la
l'affichage. position de la tête de lecture, le mode d’accès au fichier (lecture ou écriture) ... Ces
informations sont rassemblées dans une structure FILE. La manipulation de fichiers se fait à
travers un pointeur sur cette structure. Un objet de type POINETEUR(FILE) est appelé flot
de données (stream en anglais).

VII.3.1 Ouverture de fichiers


Mémoire centrale
Il est indispensable d'ouvrir un fichier avant tout accès à son contenu, comme il est d'ailleurs
nécessaire de le fermer dès que l'on en a plus besoin. La fonction fopen qui retourne un
pointeur sur une structure FILE permet d'ouvrir un fichier. Elle retourne NULL si l'opération
d'ouverture échoue.

POINTER(FILE) fopen (STRING nom, STRING mode)


Fig. 26 - Communication entre un ordinateur et les périphériques
Le premier argument de la fonction fopen est le chemin absolu ou relatif indiquant où se
trouve/où doit être créé le fichier. Ce chemin contient bien sûr le nom du fichier. Le second
VII.2 Qu'est ce qu'un fichier argument, mode, est une chaîne de caractères qui spécifie le mode d’accès au fichier. Le
mode d'accès dépend du type de fichier en question (binaire ou texte). En effet les caractères
Logiquement, un fichier est un ensemble d'informations stockées sur une mémoire de masse
de contrôle ne sont pas les mêmes pour les deux types de fichiers. Les différents modes
(disque dur, bande magnétique, CD-ROM, DVD, BR, etc.). Au début le fichier désignait un
d’accès sont listés dans le tableau suivant :
ensemble de fiches mais ce mot est maintenant utilisé pour tout ensemble de données
constituant un bloc logique. "r" Ouverture d’un fichier texte en lecture
"w" Ouverture d’un fichier texte en écriture
Physiquement, un fichier est une suite d'octets. Les informations contenues dans le fichier ne
"a" Ouverture d’un fichier texte en écriture à la fin (ajout)
sont pas forcément de même type (un CHAR, un INT, une STRUCT ...). Selon le type de
"rb" Ouverture d’un fichier binaire en lecture
fichier, un pointeur spécifique fournit l'adresse d'une information quelconque du fichier ou
Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données
81 82
"wb" Ouverture d’un fichier binaire en écriture primitives existent pour accéder à l'information contenue dans un fichier ou pour
"ab" Ouverture d’un fichier binaire en écriture à la fin (ajout) écrire dedans.
"r+" Ouverture d’un fichier texte en lecture/écriture • Fermer le fichier : Une fois l'usage du fichier est terminé, il faut le fermer. Les
"w+" Ouverture d’un fichier texte en lecture/écriture systèmes d'exploitation gèrent des tables finies de descripteurs de fichiers et si ces
"a+" Ouverture d’un fichier texte en lecture/écriture à la fin tables sont pleines, il est impossible d'ouvrir de nouveaux fichiers. La fermeture de
"r+b" Ouverture d’un fichier binaire en lecture/écriture fichier est aussi très importante dans un environnement multi-tâches et/ou multi-
"w+b" Ouverture d’un fichier binaire en lecture/écriture utilisateurs.
"a+b" Ouverture d’un fichier binaire en lecture/écriture à la fin VII.3.3.1 Lecture / écriture d'un fichier en mode caractères
Un octet est une information codée sur 8 bits. Un caractère simple est lui même un octet.
Condition d'erreurs de manipulation de fichiers
Etant donné qu'un fichier est une suite d'octets, il est possible de les lire par un mais aussi de
• Si le mode contient la lettre "r", le fichier doit exister, sinon c’est une erreur. les écrire un quelque soit la nature du fichier (texte ou binaire). La lecture/écriture en mode
• Si le mode contient la lettre "w", le fichier peut ne pas exister. Dans ce cas, il sera créé, et caractères et donc l'accès et la manipulation de l'information contenue dans un fichier
si le fichier existait déjà, son ancien contenu est perdu. caractère par caractère.
• Si le mode contient la lettre "a", le fichier peut ne pas exister. Comme pour le cas a. Lecture en mode caractère : fgetc
précédent, si le fichier n’existe pas, il est créé ; si le fichier existe déjà, son ancien contenu
est conservé. La fonction fgetc permet de lire le caractère courant d'un fichier référencé par son
descripteur et déplace le pointeur de lecture sur le caractère suivant. Elle retourne un entier
• Si un fichier est ouvert en mode "écriture à la fin", toutes les écritures se font à l’endroit
qui est était la fin du fichier lors de l'exécution de l’ordre d’écriture. Cela signifie que si qui est le code du caractère lu. A la fin du fichier, elle retourne le caractère spécial de fin de
plusieurs processus partagent le même POINTER(FILE), résultat de l’ouverture d’un fichier EOF.
fichier en écriture à la fin, leurs écritures ne s’écraseront pas mutuellement. INT fgetc (POINTER(FILE) fp);
b. Ecriture en mode caractère : fputc
Exemple d'usage de fopen
La fonction fputc permet d'écrire un caractère dans un fichier référencé par son descripteur.
POINTER(FILE) fp;
... INT fputc (CHAR c, POINTER(FILE) fp);
IF ((fp ← fopen ("monfic.txt", "r")) = NULL) THEN La variable d'entrée c représente le caractère à écrire, fp est le descripteur du fichier dans
write ("Impossible d'ouvrir le fichier"); lequel il faut écrire le caractère c. Si l'opération d'écriture se passe bien alors le code du
END IF caractère écrit est retourné sinon c'est la valeur EOF qui est retournée par fputc.

VII.3.2 Fermeture de fichiers L'algorithme suivant (algo. 54) permet de copier un fichier dans un autre. Si le fichier à
copier est un fichier binaire, il faut l'ouvrir en mode "rb" et ouvrir le fichier copie en mode
La fonction fclose permet de fermer un flot qui a été associé à un fichier par l'intermédiaire "wb", sinon il faut ouvrir le fichier source en mode "r" ou "rt" et le fichier destination en mode
de la fonction fopen. La syntaxe de fclose est la suivante : "w" ou "wt".

PROCEDURE copier (INPUT STRING nomsrc, INPUT STRING nomdest)


INT fclose (POINTER(FILE) fp);
/* ****************************************************************** *
La fonction fclose retourne 0 si la fermeture du fichier a bien eu lieu sinon, elle retourne * nomsrc : nom du fichier source à copier. Ce fichier doit exister *
EOF. La valeur EOF (End Of File) indique la fin du fichier. * nomdest : nom du fichier destination. Si ce fichier existe il sera *
* ecrasé *
VII.3.3 Manipulation de fichiers * ****************************************************************** */

BEGIN
La manipulation de fichiers se fait avec les opérations standards : ouverture, lecture/écriture
POINTER(FILE) src; // Fichier source
et fermeture. POINTER(FILE) dst; // Fichier destination
• ouvrir un fichier : lui associer une variable que l'on appelle descripteur de fichier. ENITER c; // Caractère à lire / écrire
Cette variable établit un lien univoque établit avec le fichier physique. Un descripteur
ne peut pas représenter simultanément deux fichiers différents. C'est à travers ce IF (src ← fopen (nomsrc, "rb")) == NULL THEN
descripteur qu'un programmeur peut agir sur un fichier. write ("ouverture impossible du fichier : ", nomsrc);
exit (1); // La fonction exit permet de quitter l'algo.
• Lire ou écrire des informations : une fois un descripteur est associé à un fichier, il est END IF
possible de lire à partir et/ou écrire dans le fichier correspondant. Moult de

Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données
83 84
IF (dst ← fopen (nomdest, "wb")) == NULL THEN Format Conversion Ecriture
write ("création impossible du fichier : ", nomdest); %d INT Décimale signée
exit (1); %u INT Décimale non signée
END IF %o INT Octale non signée
%x INT Hexadécimale non signée
WHILE (c ← fgetc (src)) ≠ EOF DO %f REAL Décimale en virgule fixe
fputc (c, dst); %e REAL Décimale exponentielle
END WHILE %c CHAR Caractère
%s STRING Chaîne de caractères
fclose (src);
fclose (dst); a. La fonction de lecture : fscanf
END
La fonction fscanf permet de lire des données dans un fichier. Sa syntaxe est la suivante :
Algo 54. - Copie de fichier binaire en mode caractères
INT fscanf (POINTER(FILE) fp, STRING format, arg1, arg2, ...);

VII.3.3.2 Traitement de fichiers texte fscanf permet de lire des entiers, des réels, des caractères. En général, format du fichier
(manière dont sont organisées les données) est connu avant la lecture.
Un fichier texte peut contenir des données à caractère texte ou numérique par exemple.
Problème : connaissant comment est structuré un fichier texte, comment accéder aux  fp est un descripteur de fichier où se fera la lecture
données et différencier ce qui est texte de ce qui est numérique et lire, lorsque c'est  format est une STRING qui indique le format (type de données) des valeurs à lire.
numérique, directement la valeur correspondante ? Exemple : une ligne contenant "prix : 12  argi sont les valeurs à lire selon le format indiqué par la chaine format. Les formats
dinars" est constituée des chaînes de caractères : "prix", ":", "12" et "dinars". Comment lire la de lecture / écriture sont abordés un peu plus loin.
valeur 12 au lieu de la chaîne "12" ? Même question lorsqu'il s'agit d'écriture, comment écrire Exemple : une fiche de renseignement. On a collecté quelques informations sur une
la chaîne "12" lorsque je dispose de la valeur numérique 12 ? Solution : les entrées / sorties personne: prénom, nom, âge, taille en m et poids en kg. Le fichier texte est le suivant:
formatées. Om Essaad
Principe : ressemblance avec saisies (read) et affichage (write) mais avec des sources (de Erragued
37
saisie) et destinations (d'affichage) différentes. En fait, une saisie est une lecture depuis le
1.48
clavier. On peut faire ces lectures à partir d'autres dispositifs d'entrées ou flots d'entrée. Un 97
fichier peut jouer ce rôle. De même, un affichage est une écriture vers l'écran. Écritures
possibles vers d'autres dispositifs de sortie ou flots de sortie. Un fichier peut aussi jouer ce Avec le délimiteur EOL et le caractère de fin de fichier EOF, le fichier se présente comme
rôle. suit:
Om EssaadEOLErraguedEOL37EOL1.48EOL97EOF
Le descripteur, indique, entre autres, l'endroit du fichier où se déroule la prochaine
opération. Après une ouverture, le descripteur indique la première valeur (en fait le premier ALGORITHM lecture
octet du fichier). A chaque fois qu'un opération a lieu, le descripteur indiquera l'endroit où BEGIN
s'est terminée cette opération, et donc là où aura lieu la suivante. Exemples : si on lit 4 octets, POINTER(FILE) fildesc;
le descripteur indiquera 4 octets plus loin que là ou il était. STRING nom, prenom;
INT age, poids;
Un fichier texte est constitué de lignes, chacune contenant des caractères imprimables et des
caractères de contrôle (caractères spéciaux pour le représentation du texte). Les lignes sont REAL taille;
terminées par caractère l'un de ces caractères spéciaux : EOL (End Of Line) ; c'est un IF (fildesc ← fopen("data.txt","r")) = NULL THEN;
délimiteur qui sert de point de repère pour aller à la ligne suivante lors de l'affichage. write ("Impossible d’ouvrir le fichier data.txt");
ELSE
L'accès aux fichiers texte se fait de manière séquentielle. On accède au premier élément du
fscanf (fildesc, "%s", prenom);
fichier, on ne sait pas combien de lignes il y a, ni combien de caractère sur chaque ligne. On
fscanf (fildesc, "%s", nom);
peut juste demander si on est à la fin du fichier ou non.
fscanf (fildesc, "%d", age);
Avant d'aborder les entrées / sorties, on commence par présenter les formats de lecture / fscanf (fildesc, "%f", taille);
écriture. Ces formats sont des indications passées aux fonctions sur le type de donnée à lire / fscanf (fildesc, "%d", poids);
écrire la façon dont il doit être lu / écrit. Les formats que nous utilisons en algorithmique fclose (filedesc);
sont présentés dans la table suivante. Le langage C qui utilise les entrées/sorties formatées
END IF
propose plus d'options. END
Algo 55. - Lecture formatée avec fscanf à partir d'un fichier texte

Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données
85 86
Il est possible de lire le fichier caractère par caractère avec le format %c. Le comportement de b. La fonction d'écriture : fprintf
l'algorithme est le même que celui qui utilise fgetc mais l'approche est différente. Le principe
de l'algorithme consiste à lire un caractère dans le fichier, l'afficher à l'écran dans une boucle La fonction fprintf permet d’écrire des données dans un fichier. Sa syntaxe est :
tant que la fin du fichier n'est pas atteinte. La fin du fichier est détectée par la fonction feof :
INT fprintf (POINTER(FILE) fp, STRING format, arg1, arg2, ...);
INT feof (POINTER(FILE) fp);
 la valeur de retour indique le nombre de caractères écrits.
feof indique la fin du fichier si la valeur de retour est 0, sinon la valeur de retour est non  fp : descripteur de fichier sur lequel on veut lire.
nulle.  Le caractère spécial EOL écrit dans un fichier provoquera un passage à la ligne.
 le caractère de fin de fichier EOF est ajouté automatiquement, pas besoin de le
mettre.
ALGORITHM lecture2
BEGIN Exemple (algo. 57) : on veut créer un nouveau fichier dans lequel on va écrire le même type
POINTER(FILE) fildesc; d'information que celui lu dans l'exemple de l'algo. 55 :
CHAR c;
ALGORITHM ecriture
IF (fildesc ← fopen("data.txt","rt")) = NULL THEN; BEGIN
write ("Impossible d’ouvrir le fichier data.txt"); STRING prenom ← "Yasser";
ELSE STRING nom ← "Farhan";
write ("Lecture du fichier …"); INT age ← 28;
REAL taille ← 1.84;
WHILE NOT feof (fildesc) DO
INT poids ← 95;
fscanf (fildesc, "%c", c); POINTER(FILE) ficdata;
write (c); IF (ficdata ← fopen ("data.txt","rt")) = NULL THEN;
END WHILE write ("Impossible d’ouvrir le fichier data.txt");
ELSE
fclose (fildesc); fprintf (ficdata, "%sEOL%sEOL%dEOL%fEOL%dEOL", nom, prenom,
END IF age, taille, poids);
END fclose (ficdata);
END IF
Algo 56. - Lecture caractère par caractère avec fscanf à partir d'un fichier texte END
Algo 57. - Ecriture avec fprintf dans un fichier texte
Il est bien sûr possible d'avoir plusieurs valeurs sur une ligne. Il faut alors bien choisir le
format en conséquence. Exemple : fichier texte nommé vals.txt contenant une suite de
Il y a finalement deux fonction permettant de lire ou écrire ligne par ligne : fgets et fputs.
coordonnées de points en 2 dimensions. Chaque ligne comporte deux éléments à lire. On
peut lire le contenu du fichier de plusieurs manières :
La fonction fgets lit une ligne de données d'un fichier jusqu'au caractère spécial de fin de
ligne EOL puis ajoute le terminateur de chaîne de caractère: '\0'. Cette fonction renvoie la
 Lire individuellement chaque valeur de type REAL par un fscanf
valeur NULL (non EOF!) lorsqu'on tente de lire au-delà de la fin du fichier. La syntaxe
 Lire les deux valeurs de chaque ligne par un seul fscanf.
d'appel de fgets est la suivante :
On reprend le programme précédent; on déclare deux REAL val1 et val2 au lieu de CHAR c.
STRING fgets (STRING str, INT nbcar, POINTER(FILE) fp);
On effectue 6 lectures d'un REAL dans la boucle, sans gérer la fin de fichier :
 la variable str représente l'endroit où la ligne lue sera stockée.
fscanf (fildesc, "%f", val1);  la variable nbcar est le nombre maximal de caractère à lire il faut compter dans nb le
écrire (val1); Répété 6 fois
valeur 0 (terminateur de chaîne de caractères.
 fp représente le descripteur du fichier à partir duquel on va lire les lignes.
Ou  La fonction retourne l'adresse de str si tout se passe bien sinon elle retourne NULL.

la fonction fputs ne diffère pas trop de fprintf. Sa syntaxe est la suivante :


fscanf (fildesc, "%f %f", val1, val2);
Répété 3 fois
écrire (val1, val2); INT fputs (STRING str, POINTER(FILE) fp);

Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données
87 88
 la variable str représente la chaîne de caractères à écrire. Si on veut écrire une ligne, Les inconvénients sont :
il faut ajouter le caractère EOL à la fin.
 fp représente le descripteur du fichier dans lequel on va écrire. • Non éditable par l’utilisateur.
 La fonction retourne un entier positif si l'écriture de passe bien sinon elle retourne • Illisible pour l’utilisateur.
EOF. • Donnée non directement transférables d’un ordinateur à l’autre. Le problème concerne
le choix de représentation des entiers de plusieurs octets : poids faible en premier (little-
l'appel fputs (str, fic) est équivalent à l'appel fprintf (fic, "%s", str). endian : 80x86, pentium), poids fort en premier (big-endian : MC68000, réseau IP, ...),
autre ordre... Il faut alors prendre des précautions qui ne sont pas si simples.)
Dans l'exemple suivant (algo. 58) on fait la copie d'un fichier texte dans un autre par l'usage
des fonction fgets et fputs. De même que pour un fichier texte, avant d'utiliser un fichier binaire, il faut l'ouvrir et
lorsque l'usage du fichier est terminé, il faut le fermer.
ALGORITHM copier (INPUT STRING nomsrc, INPUT STRING noomdest)
BEGIN
POINTER(FILE) src; // Fichier source
Il y a deux types d'accès possibles pour les fichiers binaires :
POINTER(FILE) dst; // Fichier destination
STRING str; // Caractère à lire / écrire • L'accès séquentiel : les éléments sont lus ou écrits l’un après l’autre dans le fichier.
• L'accès direct : les éléments sont écrits à une position donnée. La position courante
IF (src ← fopen (nomsrc, "r")) == NULL THEN d’écriture est déplacée en cours d’utilisation. Les bases de données représentent une
write ("ouverture impossible du fichier : ", nomsrc); application typique des fichiers binaires.
exit (1); // La fonction exit permet de quitter l'algo.
END IF
VII.3.3.3.1 Les entrées / sorties en mode binaire
IF (dst ← fopen (nomdest, "w")) == NULL THEN
write ("création impossible du fichier : ", nomdest); Les fonctions d’entrées-sorties binaires permettent de transférer des données dans un fichier
exit (1); sans transcodage. Elles sont donc plus efficaces que les fonctions d’entrée-sortie standard,
END IF mais la nature des fichiers produits dépend de l'architecture des machines (little-endian, big-
endian, etc.). Ces fonctions d'entrées-sorties (fread et fwrite) sont notamment utiles pour
WHILE (fgets (str, 100, src)) ≠ NULL DO manipuler des structures de données de grande taille ou ayant un type composé (STRUCT).
fputs (str, dst);
END WHILE Leurs prototypes sont :

fclose (src); INT fread (POINTER(VOID) t, INT s, INT c, POINTER(FILE) f);


fclose (dst);
END INT fwrite (POINTER(VOID) t, INT s, INT c, POINTER(FILE) f);
Algo 58. - copie de fichier texte avec fgets et fputs
Le rôle des paramètres de ces deux fonctions sont :
VII.3.3.3 Traitement de fichiers binaire • t est un un tampon :
Un fichier binaire est un fichier qui contient directement la représentation mémoire des  zone de mémoire destinée à recevoir les données pour fread.
informations. Un fichier binaire peut aussi être vu comme une séquence d’octets (écrits à la
queue leu leu) qui dans tous les cas possède une structure, même si elle n’est pas apparente.  zone de mémoire où se trouvent les éléments à écrire dans le fichier pour
Un REAL sera donc stocké dans un fichier binaire sous la forme de quatre octets qui fwrite.
constituent sa représentation dans la norme IEEE. Contrairement aux fichiers texte où • Le type POINTER(VOID) : indique un pointeur sur un type qui n'est pas encore défini,
chaque octet est un caractère imprimable, les octets dans un fichier binaire peuvent il permet de la souplesse en utilisant le transtypage.
représenter autre chose. Un exemple de fichier binaire est le résultat de la compilation d’un • Les variables s (pour size) et c (pour count) sont des entiers non signés. La variable s
programme C (programme exécutable). indique la taille en octets d'un élément complexe à lire/écrire, cela permet de décaler
correctement le descripteur. La variable c indique le nombre d'éléments complexes à
Les avantages d'un fichier binaire sont : lire/écrire.
• POINTER(FILE) f : le descripteur du fichier qui est concerné par cette opération
• Ils sont plus rapide que les fichiers textes puisqu'il n'y a pas de conversion.
d'entrée/sortie.
• L'accès aux données peut être direct puisque les informations ont longueur fixe. Pour • La valeur de retour est le nombre d'éléments complexes effectivement lus grâce à
accéder à la i-ème information, il suffit d’atteindre l'octet à la position POS (temps fread/enregistrés grâce à fwrite. Pour fread, ce nombre peut être plus petit que le
presque constant)). Le calcul de POS est le suivant : paramètre count si on rencontre la fin de fichier.
POS = i × taille (information)
Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données
89 90
VII.3.3.3.2 Exemples • Déclarer un tableau contenant des valeurs de type complex;
• Initialiser le tableau;
EXEMPLE 1 : L'algorithme suivant (algo. 59) écrit un tableau d’entiers (contenant les 50 • ouvrir un fichier binaire en écriture
premiers entiers) avec fwrite dans le fichier sortie, puis lit ce fichier avec fread et imprime les • si l'ouverture s'est bien déroulée
éléments du tableau.  écrire les éléments du tableau dans le fichier
 fermer le fichier
ALGORITHM fic_binaire
BEGIN
 rouvrir le fichier en lecture
POINTER(FILE) fic; // Fichier qui servira pour stocker les entiers  lire le fichier et stocker les structures de données représentant les nombres
INT tab1 []; // Le tableau à copier dans le fichier complexes dans un autre tableau.
INT tab2 []; // Le tableau à remplir à partir du fichier
INT i; ALGORITHM fic_binaire2
CONST INT NB = 50; BEGIN
complex tabc_src [3] ← {{1.0, 1.0},{2.0, 3.0},{3.0, -1.0}};
tab1 ← POINTER(INT) malloc (NB * sizeof (INT));
tab2 ← POINTER(INT) malloc (NB * sizeof (INT)); complex tabc_dst [3];
POINTER(FILE) ficbin;
FOR i ← 0 TO NB - 1 DO
tab1 [i] ← i; IF (ficbin ← fopen ("comp.bin", "wb")) ≠ NULL THEN
END FOR
fwrite (tabc_src, SIZEOF (complex), 1, ficbin);
// ecriture du tableau dans le fichier de sortie res.dat fwrite (tabc_src + 1, SIZEOF (complex), 2, ficbin);
IF (fic ← fopen ("res.dat", "wb")) = NULL THEN fclose (ficbin);
write ("Impossible d’écrire dans le fichier res.dat");
exit (1);
END IF IF (ficbin ← fopen ("comp.bin", "rb")) ≠ NULL THEN
fread (tabc, SIZEOF (complex), 3, ficbin);
fwrite (tab1, NB * sizeof (INT), 1, fic); fclose (ficbin);
fclose (fic); END IF
// lecture dans le fichier res.dat
IF (fic ← fopen ("res.dat", "rb")) = NULL THEN END IF
write ("Impossible de lire dans le fichier res.dat"); END
exit (1);
END IF On peut remplacer les 2 instructions fwrite par un seul :
fread (tab2, NB * sizeof (INT), 1, fic); fwrite (tabc, SIZEOF (complex), 3, ficbin);
fclose (fic);
VII.3.3.3.3 Accès directe aux données dans un fichier binaire
FOR i ← 0 TO NB - 1 DO
write (tab2[i]);
END FOR La fonction fseek permet de se déplacer dans le fichier d'un certain nombre d'octets. Par
END exemple, on doit aller lire le kième élément stocké dans un fichier binaire, la valeur des
Algo 59. - copie de fichier d'un tableau d'entiers dans un fichier binaire et lecture du fichier résultat
éléments précédents en nous intéresse pas. La syntaxe de fseek est :

INT fseek (POINTER(FILE) fic, INT depl, INT origin );


EXEMPLE 2 : Un tableau contenant des données de type STRUCT représentant des nombres
complexes qu'il faut stocker dans un fichier binaire. La structure est définie ainsi : • La fonction fseek renvoie la valeur 0 si elle a bien fonctionné.
• fic : le fichier sur lequel on travaille
TYPEDEF STRUCT complex
• depl : valeur du déplacement en nombre d'octets : si l'on connaît la taille en octets d'un
BEGIN élément (on le peut grâce à sizeof), on multiplie par le nombre d'éléments pour obtenir
REAL r; /* Partie réelle */ cette valeur.
REAL i; /* Partie imaginaire */ • Origin : indique à partir de quel endroit du fichier est calculé le déplacement, il a 3
END; valeurs possibles seulement :
Que va faire le programme (algo. 60):

Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données
91 92
 SEEK_CUR : par apport à la position actuelle.
 SEEK_END : par rapport à la fin du fichier.
 SEEK_SET : par rapport au début du fichier.

EXEMPLE : Exemple : avec le fichier contenant les valeurs des nombres complexes, on veut
seulement lire la troisième valeur sans se préoccuper des autres. On va ouvrir le fichier, puis
déplacer le descripteur pour aller directement là ou se trouve les valeurs du 3ème élément.
Pour cela, on doit se décaler de 2 éléments à partir du début du fichier. Le calcul du nombre
d'octets à ignorer est simple, c'est la taille de deux complexes : 2 * sizeof (complex) !

fseek (ficbin, 2 * SIZEOF (complex), SEEK_SET);

EXEMPLE : Cet autre exemple, toujours avec l'exemple sur les nombres complexes, consiste,
après avoir lu le 3ème complexe avec fread, à revenir un élément en arrière dans le fichier.
On se déplacera à partir de l'endroit où l'on se trouve, le nombre d'octets du déplacement
sera donné par : 1 * sizeof (complex); De plus le déplacement se fait en arrière, il faut donc
passer une valeur négative :

fseek (ficbin, -SIZEOF (complex), SEEK_CUR);

VII.3.4 Autres opérations sur les fichiers

Il y a beaucoup d'autres opérations possibles sur les fichiers, certaine d'ordre général
s'appliquant sur n'importe quel type de fichier et d'autres s'appliquant sur un type bien
particulier, par exemple les fichiers binaires.

Parmi les opérations d'ordre général les plus utilisées on trouve les fonction rename qui
permet de renommer un fichier et remove qui permet de supprimer un fichier.

INT rename (STRING src, STRING dest);

INT remove (STRING fname);

• Les paramètres de la fonction rename sont src, le nom du fichier à renommer et dest le
nouveau nom à associer au fichier. Un fichier dont le nom est src doit exister sinon il y a
erreur. Si tout se passe bien, le fichier est renommé et son nouveau nom est le contenu
de la variable dest.
• L'unique paramètre de la fonction remove est le nom du fichier à supprimer (fname). Ce
fichier doit exister sur le disque pour que l'opération se déroule correctement.
• Les deux fonctions retournent la valeur 0 (zéro) si tout se passe bien, autrement la valeur
retournée est différent de 0.
• Le fichier à renommer ne doit pas être ouvert, sinon on ne peut exécuter ni rename ni
remove.

Ecole Polytechnique de Tunisie | Cours Algorithmique et Structures de Données


93

Vous aimerez peut-être aussi