Académique Documents
Professionnel Documents
Culture Documents
Les Fichiers
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.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".
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.
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 :
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) !
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 :
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.
• 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.