Cours Atelier de Programmation Avancée - Fichiers Binaires
Ce cours présente la manipulation des fichiers binaires en langage C à travers l'utilisation des fonctions fread, fwrite, fseek, ftell et feof. Il détaille l'accès séquentiel et direct sur des structures de données.
D'après le document Cours Atelier de Programmation Avancée - Fichiers Binaires
Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

Document source
Computer Science · PDF · 10 pages · 2011
Afficher l'aperçu du document
Ce laboratoire pratique porte sur la manipulation des fichiers binaires en langage C. Il permet d’apprendre à lire, écrire, modifier et parcourir des fichiers contenant des données structurées, notamment des entiers et des structures complexes comme des enregistrements d’étudiants. Pour réaliser ce TP, il est nécessaire de disposer d’un environnement de programmation C avec un compilateur supportant les fonctions standard d’entrée/sortie (stdio.h).
Objectifs du cours
- Comprendre la différence entre fichiers binaires et fichiers texte.
- Utiliser les fonctions fread et fwrite pour lire et écrire des données binaires.
- Gérer l’ouverture, la fermeture et le positionnement dans un fichier avec fopen, fclose, fseek et ftell.
- Manipuler des structures complexes dans des fichiers binaires.
- Mettre en œuvre un accès direct aux données dans un fichier binaire.
- Détecter la fin de fichier avec feof.
Prérequis et configuration minimale
- Connaissances de base en langage C, notamment les pointeurs et les structures.
- Compréhension des notions de fichiers et de flux en C.
- Environnement de développement C avec accès aux bibliothèques standard (stdio.h, stdlib.h).
- Terminal ou console pour saisir les données et exécuter les programmes.
Notions fondamentales des fichiers binaires en C
En C, un fichier est une suite ordonnée d’octets. Contrairement aux fichiers texte, les fichiers binaires stockent les données telles qu’elles sont en mémoire, sans conversion en caractères lisibles. Cette méthode est rapide et efficace mais moins portable entre différents environnements.
Les fonctions principales pour manipuler les fichiers binaires sont :
fwrite(&bloc, sizeof(bloc), n, fp): écrit n blocs de taille sizeof(bloc) à partir de l’adresse &bloc dans le fichier fp.fread(&bloc, sizeof(bloc), n, fp): lit au maximum n blocs de taille sizeof(bloc) depuis le fichier fp vers l’adresse &bloc.fopen(nom, mode): ouvre un fichier avec un mode donné (lecture, écriture, binaire, etc.) et retourne un pointeur de type FILE*.fclose(fp): ferme le fichier associé au flux fp.feof(fp): indique si la fin du fichier a été atteinte après une tentative de lecture.fseek(fp, offset, origine): déplace le pointeur de fichier à une position précise.ftell(fp): retourne la position actuelle du pointeur dans le fichier.
Création et affichage d’un fichier binaire d’entiers
Cette première étape consiste à créer un fichier binaire dans lequel l’utilisateur saisit des entiers, puis à afficher le contenu du fichier.
Procédure :
- Demander à l’utilisateur le nom du fichier à créer.
- Ouvrir ce fichier en mode
"wb+"(écriture et lecture en binaire, création du fichier). - Dans une boucle, demander à l’utilisateur de saisir un entier. Si l’entier est différent de 0, l’écrire dans le fichier avec
fwrite. - Arrêter la saisie lorsque l’utilisateur entre 0.
- Revenir au début du fichier avec
rewind(fp). - Lire et afficher tous les entiers du fichier jusqu’à la fin (détectée avec
feof). - Fermer le fichier avec
fclose(fp).
Résultat attendu : Tous les entiers saisis (hors 0) doivent s’afficher dans l’ordre.
Exemple de code :
#include <stdio.h>
void main() {
char nomfich[21];
int n;
FILE *fp;
printf("saisir nom fichier ");
scanf("%s", nomfich);
fp = fopen(nomfich, "wb+");
do {
printf("donner un entier; 0 pour s'arreter ");
scanf("%d", &n);
if (n != 0) fwrite(&n, sizeof(int), 1, fp);
} while (n != 0);
rewind(fp);
while (!feof(fp)) {
fread(&n, sizeof(int), 1, fp);
if (!feof(fp)) printf("\n %d\n", n);
}
fclose(fp);
}
Manipulation d’un fichier binaire d’étudiants
Cette étape montre comment manipuler un fichier binaire contenant des enregistrements d’étudiants, chacun défini par une structure comportant un numéro de carte, un nom, un tableau de notes et une date de naissance.
Définition des structures :
struct date {
int jour;
int mois;
int annee;
};
typedef struct date DATE;
struct etudiant {
int ce; // numéro carte d’étudiant
char nom[30];
float notes[5];
DATE date_naiss;
};
typedef struct etudiant ETUDIANT;
Procédure :
- Ouvrir un fichier en mode
"wb+". - Remplir le fichier avec des étudiants saisis par l’utilisateur. La saisie s’arrête lorsque le numéro de carte est égal à -1.
- Pour chaque étudiant, saisir le numéro de carte, le nom, les 5 notes, et la date de naissance.
- Écrire chaque étudiant dans le fichier avec
fwrite. - Revenir au début du fichier avec
rewind(fp). - Lire et afficher tous les étudiants jusqu’à la fin du fichier.
- Fermer le fichier.
Fonctions utiles :
saisir_etudiant(ETUDIANT *e): saisit un étudiant, retourne 0 si ce = -1 (fin).remplir_notes(float *t): saisit 5 notes dans un tableau.afficher_notes(float *t): affiche les 5 notes.affichage_fichier(FILE *fp): lit et affiche tous les étudiants du fichier.
Extrait de code pour la saisie et l’affichage :
int saisir_etudiant(ETUDIANT *e) {
printf("\n saisir ce \n");
scanf("%d", &e->ce);
if (e->ce == -1) return 0;
printf("\n saisir nom ");
scanf("%s", e->nom);
printf("\n saisir les notes ");
remplir_notes(e->notes);
printf("\n saisir la date de naissance \n");
scanf("%d%d%d", &e->date_naiss.jour, &e->date_naiss.mois, &e->date_naiss.annee);
return 1;
}
void remplir_fichier(FILE *fp) {
ETUDIANT etd;
while (saisir_etudiant(&etd))
fwrite(&etd, sizeof(ETUDIANT), 1, fp);
}
void affichage_fichier(FILE *fp) {
ETUDIANT etd;
while (1) {
fread(&etd, sizeof(ETUDIANT), 1, fp);
if (feof(fp)) break;
printf("\n %4d %20s \n", etd.ce, etd.nom);
afficher_notes(etd.notes);
printf("\n %2d %2d %4d \n", etd.date_naiss.jour, etd.date_naiss.mois, etd.date_naiss.annee);
}
}
Modification d’un enregistrement par accès direct
L'accès direct avec fseek permet de modifier un étudiant à une position donnée dans un fichier binaire sans avoir à lire les enregistrements précédents.
Procédure :
- Ouvrir le fichier en mode
"wb+"et remplir les données. - Revenir au début du fichier avec
rewind(fp). - Demander à l’utilisateur la position (numéro d’enregistrement) de l’étudiant à modifier.
- Positionner le pointeur de fichier à l’enregistrement choisi avec
fseek(fp, (pos-1)*sizeof(ETUDIANT), SEEK_SET). - Lire l’étudiant à cette position avec
freadet l’afficher. - Modifier les informations de l’étudiant avec une fonction dédiée.
- Revenir à la même position dans le fichier avec
fseek. - Écrire les nouvelles données avec
fwrite. - Revenir au début du fichier et afficher le contenu complet pour vérifier la modification.
- Fermer le fichier.
Extrait de code pour modifier un étudiant :
void modifier_etudiant(ETUDIANT *e) {
printf("\n saisir les nouvelles infos de l'etudiant \n");
printf("\n saisir ce \n");
scanf("%d", &e->ce);
printf("\n saisir nom ");
scanf("%s", e->nom);
printf("\n saisir les notes ");
remplir_notes(e->notes);
printf("\n saisir la date de naissance \n");
scanf("%d%d%d", &e->date_naiss.jour, &e->date_naiss.mois, &e->date_naiss.annee);
}
void main() {
FILE *fp;
int pos;
long p;
ETUDIANT etd;
ouverture(&fp);
remplir_fichier(fp);
rewind(fp);
printf("saisir la position de l'etudiant à modifier ");
scanf("%d", &pos);
fseek(fp, (pos-1) * sizeof(ETUDIANT), SEEK_SET);
p = ftell(fp);
fread(&etd, sizeof(ETUDIANT), 1, fp);
afficher_etudiant(etd);
modifier_etudiant(&etd);
fseek(fp, p, SEEK_SET);
fwrite(&etd, sizeof(ETUDIANT), 1, fp);
rewind(fp);
affichage_fichier(fp);
fclose(fp);
}
Utilisation avancée des fonctions fseek et ftell
La fonction fseek déplace le pointeur de fichier à n’importe quelle position pour l'accès direct, tandis que ftell retourne la position actuelle du pointeur afin de mémoriser ou mesurer des emplacements.
Modes de déplacement avec fseek :
SEEK_SET(0) : déplacement à partir du début du fichier.SEEK_CUR(1) : déplacement à partir de la position courante (peut être négatif).SEEK_END(2) : déplacement à partir de la fin du fichier.
Exemple d’utilisation :
fseek(fp, sizeof(int) * (pos-1), SEEK_SET); // positionne au pos-ème entier
long p = ftell(fp); // mémorise la position actuelle
// ... opérations de lecture ou écriture ...
fseek(fp, p, SEEK_SET); // revient à la position mémorisée
On peut également obtenir la taille d’un fichier et calculer le nombre d’enregistrements :
fseek(fp, 0, SEEK_END);
long taille = ftell(fp);
printf("la taille du fichier est %ld", taille);
printf("\n le nombre d'enregistrements est %ld", taille / sizeof(ETUDIANT));
Résultats attendus lors des exécutions
- Les fichiers binaires créés contiennent les données saisies sans perte ni corruption.
- Les entiers ou structures lus correspondent exactement aux données écrites.
- La lecture séquentielle affiche tous les enregistrements dans l’ordre.
- La modification d’un enregistrement à une position donnée est correctement prise en compte.
- Les fonctions fseek et ftell permettent un accès direct fiable aux données.
- La détection de la fin de fichier avec feof fonctionne correctement, évitant les lectures invalides.
Pièges courants et bonnes pratiques
- Ne pas vérifier que le fichier s’est bien ouvert (pointeur NULL) avant de lire ou écrire.
- Utiliser feof avant une lecture : feof ne devient vrai qu’après une tentative de lecture au-delà de la fin.
- Confondre les deux formes d’appel de fread/fwrite :
fread(&bloc, sizeof(bloc), n, fp)vsfread(&bloc, n*sizeof(bloc), 1, fp). En cas d’erreur, la première peut lire/écrire partiellement, la deuxième échoue complètement. - Oublier de repositionner le pointeur de fichier avec rewind ou fseek avant une nouvelle lecture après écriture.
- Ne pas prendre en compte la taille exacte des structures lors du calcul des positions dans le fichier.
- Utiliser des fonctions obsolètes ou dangereuses comme
gets(préférerfgetsouscanfavec limite de taille). - Ne pas gérer correctement la saisie des chaînes de caractères (risque de dépassement de tampon).
Commentaires
Aucun commentaire pour le moment. Posez la première question.