Lecture et écriture dans les fichiers
C fournit trois niveaux de fonctions pour lire et écrire dans les fichiers : caractère par caractère (fgetc/fputc), chaîne par chaîne (fgets/fputs), et données formatées ou binaires (fscanf/fprintf, fread/fwrite).
| Niveau | Écriture | Lecture | Mode fichier | Usage typique |
|---|---|---|---|---|
| Caractère | fputc() | fgetc() | Texte | Copie octet par octet |
| Chaîne | fputs() | fgets() | Texte | Lecture/écriture de lignes |
| Formaté | fprintf() | fscanf() | Texte | Données structurées lisibles |
| Binaire | fwrite() | fread() | Binaire ("wb"/"rb") | Structures, tableaux, performance |
1. fputc() et fgetc() — Caractère par caractère
int fputc(int ch, FILE *fp);
/* Écrit le caractère ch dans le fichier fp
Retourne la valeur ASCII de ch, ou EOF en cas d'erreur */
int fgetc(FILE *fp);
/* Lit un caractère du fichier fp et avance le curseur
Retourne la valeur ASCII du caractère, ou EOF en fin de fichier / erreur */fputc, les caractères s'accumulent dans le buffer et sont écrits en bloc sur disque dès que le buffer est plein ou que le fichier est fermé. Pour fgetc, un bloc entier est lu depuis le disque dans le buffer ; les caractères sont ensuite livrés un par un — ce qui rend ces fonctions bien plus efficaces qu'une lecture/écriture disque réelle à chaque appel.Exemple n°1 — Copier l'entrée standard vers un fichier
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *f;
int ch;
f = fopen("test.txt", "w");
if (f == NULL) {
perror("Ouverture test.txt");
exit(1);
}
/* Lire depuis stdin, écrire dans le fichier jusqu'à EOF (Ctrl+D / Ctrl+Z) */
while ((ch = getchar()) != EOF) {
fputc(ch, f);
}
fclose(f);
printf("Fichier écrit.\n");
return 0;
}Exemple n°2 — Lire et afficher un fichier caractère par caractère
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *f;
int ch;
f = fopen("test.txt", "r");
if (f == NULL) {
perror("Ouverture test.txt");
exit(1);
}
while ((ch = fgetc(f)) != EOF) {
printf("%c", ch);
}
fclose(f);
return 0;
}Exemple n°3 — Compter les caractères et les lignes d'un fichier
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *f;
int ch, nb_chars = 0, nb_lines = 0;
f = fopen("test.txt", "r");
if (f == NULL) { perror("Ouverture"); exit(1); }
while ((ch = fgetc(f)) != EOF) {
nb_chars++;
if (ch == '\n') nb_lines++;
}
printf("Caractères : %d\n", nb_chars);
printf("Lignes : %d\n", nb_lines);
fclose(f);
return 0;
}Caractères : 14 Lignes : 2
2. fputs() et fgets() — Chaîne par chaîne
int fputs(const char *str, FILE *fp);
/* Écrit la chaîne str dans fp (sans ajouter '\n' automatiquement)
Retourne une valeur >= 0 en cas de succès, EOF en cas d'erreur */
char *fgets(char *str, int n, FILE *fp);
/* Lit au plus n-1 caractères depuis fp dans str, s'arrête à '\n' ou EOF
Ajoute '\0' en fin — conserve le '\n' dans str
Retourne str en cas de succès, NULL en fin de fichier ou erreur */| Critère | fputs() | fgets() |
|---|---|---|
| Direction | Écriture (mémoire → fichier) | Lecture (fichier → mémoire) |
| Saut de ligne | Non ajouté automatiquement | Conservé dans la chaîne lue |
| Limite taille | Non (écrit toute la chaîne) | Oui — paramètre n |
| Fin de fichier | — | Retourne NULL |
Exemple n°4 — Écrire des lignes saisies dans un fichier
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
FILE *f;
char ligne[100];
f = fopen("notes.txt", "w");
if (f == NULL) { perror("Ouverture"); exit(1); }
printf("Saisir des lignes (ligne vide pour terminer) :\n");
while (fgets(ligne, sizeof(ligne), stdin) != NULL) {
if (ligne[0] == '\n') break; /* ligne vide = fin de saisie */
fputs(ligne, f); /* écrit la ligne dans le fichier */
}
fclose(f);
printf("Fichier sauvegardé.\n");
return 0;
}Exemple n°5 — Lire et afficher un fichier ligne par ligne
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *f;
char ligne[100];
int num = 1;
f = fopen("notes.txt", "r");
if (f == NULL) { perror("Ouverture"); exit(1); }
while (fgets(ligne, sizeof(ligne), f) != NULL) {
printf("%3d | %s", num++, ligne);
}
fclose(f);
return 0;
}1 | Algorithmes et structures de données 2 | Programmation en C 3 | Bases de données
gets() La source utilise gets() dans l'exemple 3. Cette fonction est supprimée de la norme C11 car elle ne limite pas la taille de la lecture — elle provoque des dépassements de buffer exploitables. Utiliser toujours fgets(stdin)à la place :gets(str); /* Dangereux — supprimé C11 */
fgets(str, sizeof(str), stdin); /* Correct et sécurisé */3. fprintf() et fscanf() — Données formatées
fprintf() et fscanf() sont les équivalents fichier de printf() et scanf(). Ils acceptent les mêmes spécificateurs de format (%d, %s, %f…) avec un argument supplémentaire : le pointeur de fichier en première position.int fprintf(FILE *fp, const char *format, ...);
/* Comme printf() mais écrit dans fp au lieu de stdout
Retourne le nb de caractères écrits, ou EOF en cas d'erreur */
int fscanf(FILE *fp, const char *format, ...);
/* Comme scanf() mais lit depuis fp au lieu de stdin
Retourne le nb de valeurs lues, ou EOF en fin de fichier / erreur */Exemple n°6 — Écrire des données formatées
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *f;
char nom[20];
int age;
f = fopen("etudiants.txt", "w");
if (f == NULL) { perror("Ouverture"); exit(1); }
printf("Nom : ");
scanf("%s", nom);
printf("Âge : ");
scanf("%d", &age);
fprintf(f, "%s %d\n", nom, age); /* écriture formatée dans le fichier */
fclose(f);
printf("Enregistré dans etudiants.txt\n");
return 0;
}Exemple n°7 — Lire des données formatées et afficher
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *f;
char nom[20];
int age;
f = fopen("etudiants.txt", "r");
if (f == NULL) { perror("Ouverture"); exit(1); }
/* Lire jusqu'à la fin du fichier */
while (fscanf(f, "%s %d", nom, &age) == 2) {
printf("Nom : %-15s | Âge : %d\n", nom, age);
}
fclose(f);
return 0;
}Nom : Mostafa | Âge : 23 Nom : Ismail | Âge : 20 Nom : Dounia | Âge : 22
fscanf() fscanf()retourne le nombre de valeurs correctement lues. Vérifier cette valeur dans la condition de boucle protège contre les données malformées et la fin de fichier :while (fscanf(f, "%s %d", nom, &age) == 2) { ... }
/* Sortie propre si : fin de fichier, ligne mal formée, ou erreur */4. fwrite() et fread() — Mode binaire
fwrite() et fread() écrivent et lisent des blocs d'octets tels qu'ils sont représentés en mémoire — sans conversion ni formatage. Ils sont plus rapides que les fonctions texte et permettent de persister directement des structures, tableaux ou tout type de données.size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp);
/* Écrit n éléments de taille size depuis l'adresse ptr dans fp
Retourne le nombre d'éléments effectivement écrits */
size_t fread(void *ptr, size_t size, size_t n, FILE *fp);
/* Lit n éléments de taille size depuis fp vers l'adresse ptr
Retourne le nombre d'éléments effectivement lus */| Paramètre | Rôle | Exemple |
|---|---|---|
ptr | Adresse source (écriture) ou destination (lecture) | &a, tab, &etd |
size | Taille en octets d'un élément | sizeof(int), sizeof(struct etudiant) |
n | Nombre d'éléments à lire/écrire | 1, 3, N |
fp | Pointeur de fichier (ouvert en mode binaire) | f |
Exemples d'écriture avec fwrite()
Exemple n°8 — Écrire une variable, un tableau, une structure
#include <stdio.h>
#include <stdlib.h>
struct etudiant {
char nom[20];
int age;
};
int main(void)
{
FILE *f = fopen("data.bin", "wb");
if (f == NULL) { perror("Ouverture"); exit(1); }
/* Écrire une variable int */
int a = 5;
fwrite(&a, sizeof(a), 1, f);
/* Écrire un tableau */
int tab[4] = {2, 5, 7, 8};
fwrite(tab, sizeof(tab), 1, f); /* tableau entier */
/* Écrire une structure */
struct etudiant etd = {"Mostafa", 34};
fwrite(&etd, sizeof(etd), 1, f);
/* Écrire un tableau de structures (2 éléments sur 3) */
struct etudiant etds[3] = {{"Mostafa", 32}, {"Ismail", 27}, {"Dounia", 23}};
fwrite(etds, sizeof(struct etudiant), 2, f); /* seulement Mostafa et Ismail */
fclose(f);
printf("Données binaires écrites.\n");
return 0;
}Exemples de lecture avec fread()
Exemple n°9 — Lire et afficher toutes les structures d'un fichier
#include <stdio.h>
#include <stdlib.h>
struct etudiant {
char nom[20];
int age;
};
int main(void)
{
FILE *f;
struct etudiant etd;
int num = 1;
f = fopen("etudiants.bin", "rb");
if (f == NULL) { perror("Ouverture"); exit(1); }
/* Lire une structure à la fois — s'arrête quand fread retourne 0 */
while (fread(&etd, sizeof(etd), 1, f) == 1) {
printf("Étudiant N°%d : %-15s %d ans\n", num++, etd.nom, etd.age);
}
fclose(f);
return 0;
}Exemple n°10 — Écrire puis relire un tableau de structures (programme complet)
#include <stdio.h>
#include <stdlib.h>
struct etudiant {
char nom[20];
int age;
};
int main(void)
{
const int N = 3;
struct etudiant liste[3] = {
{"Mostafa", 23},
{"Ismail", 20},
{"Dounia", 22}
};
/* --- Écriture --- */
FILE *f = fopen("etudiants.bin", "wb");
if (f == NULL) { perror("Écriture"); exit(1); }
fwrite(liste, sizeof(struct etudiant), N, f);
fclose(f);
/* --- Lecture --- */
struct etudiant lu[3];
f = fopen("etudiants.bin", "rb");
if (f == NULL) { perror("Lecture"); exit(1); }
int nb = fread(lu, sizeof(struct etudiant), N, f);
fclose(f);
printf("%d enregistrements lus :\n", nb);
for (int i = 0 ; i < nb ; i++) {
printf(" %s — %d ans\n", lu[i].nom, lu[i].age);
}
return 0;
}3 enregistrements lus : Mostafa — 23 ans Ismail — 20 ans Dounia — 22 ans
fread() fread() retourne le nombre d'éléments effectivement lus, qui peut être inférieur à nen fin de fichier ou en cas d'erreur. Toujours utiliser cette valeur de retour pour détecter la fin de fichier :/* Correct — boucle sur le retour de fread */
while (fread(&etd, sizeof(etd), 1, f) == 1) { ... }
/* Vérification après fread multiple */
int nb = fread(buf, sizeof(struct etudiant), N, f);
if (nb < N) {
if (feof(f)) printf("Fin de fichier atteinte\n");
if (ferror(f)) perror("Erreur de lecture");
}Récapitulatif
| Fonction | Direction | Granularité | Mode | Retourne |
|---|---|---|---|---|
fputc(ch, f) | Écriture | 1 caractère | Texte | ASCII du char, ou EOF |
fgetc(f) | Lecture | 1 caractère | Texte | ASCII du char, ou EOF |
fputs(str, f) | Écriture | Chaîne entière | Texte | ≥ 0, ou EOF |
fgets(str, n, f) | Lecture | Ligne (max n-1 chars) | Texte | Pointeur str, ou NULL |
fprintf(f, fmt, ...) | Écriture | Données formatées | Texte | Nb chars écrits, ou EOF |
fscanf(f, fmt, ...) | Lecture | Données formatées | Texte | Nb valeurs lues, ou EOF |
fwrite(ptr, size, n, f) | Écriture | Bloc d'octets | Binaire | Nb éléments écrits |
fread(ptr, size, n, f) | Lecture | Bloc d'octets | Binaire | Nb éléments lus |
Discussion (0)
Soyez le premier à laisser un commentaire !
Laisser un commentaire
Votre commentaire sera visible après modération.