La gestion des entrées et sorties en C peut être complexe pour les développeurs débutants.
Sans une compréhension claire, cela peut entraîner des erreurs dans la manipulation des fichiers et des flux.
Cet article vous guide à travers les fonctions essentielles de stdio.h pour une manipulation efficace des entrées et sorties en C.
Développez votre expertise en C et ouvrez la voie à des projets passionnants.
Fonctions d'entrée/sortie en C : Introduction
Ce chapitre se concentrera sur les fonctions d’entrées/sorties en langage C, spécifiquement celles disponibles dans la bibliothèque standard <stdio.h>. Nous explorerons les types prédéfinis, les familles de fonctions d’écriture et de lecture formatées, ainsi que la manipulation des fichiers. Des explications approfondies, des exemples de code, et des astuces pour éviter les erreurs courantes seront fournis.
Bibliothèque en C : Présentation
La bibliothèque <stdio.h> (Standard Input Output) est l’une des bibliothèques standard du langage C, essentielle pour la gestion des entrées et sorties. Voici quelques autres bibliothèques couramment utilisées en C :
Bibliothèque | Utilisation |
---|---|
Fonctions mathématiques | |
Manipulation de caractères | |
Gestion des erreurs | |
Limites de l’arithmétique flottante | |
Limites des types entiers | |
Support des localisations | |
Utilitaires d’usage général | |
Manipulation des chaînes de caractères | |
Manipulation du temps |
Types prédéfinis : FILE et size_t
La bibliothèque <stdio.h> définit plusieurs types utiles pour la manipulation des fichiers et des flux d’entrées/sorties.
Définitions importantes :
- size_t :Type utilisé pour représenter la taille des objets en mémoire. C’est un alias pour un type entier non signé (unsigned int), souvent utilisé avec la fonction sizeof().
- FILE :Type utilisé pour gérer les fichiers dans les programmes. Il contient toutes les informations nécessaires à la gestion d’un fichier (descripteur de fichier, pointeur de fichier, etc.).
- fpos_t :Type utilisé pour stocker la position actuelle du pointeur de fichier.
Fonctions d'écriture formatée en C
Les fonctions d’écriture formatées permettent d’écrire des données sous un format spécifique sur différents types de flux (sortie standard, fichier, etc.). Voici les principales fonctions :
- printf() :Écrit sur la sortie standard (généralement l’écran).
- fprintf(FILE *stream, …) :Écrit dans un fichier ou un autre flux spécifié.
- sprintf(char *str, …) :Écrit dans une chaîne de caractères.
Utilisation de sprintf pour formater des chaînes :
#include
int main() {
char[100], chaine[200];
// Saisie de l'utilisateur
scanf("%s", prenom);
// Formatage de la chaîne
sprintf(chaine, " Bienvenu chez %s", prenom);
printf("%s\n", chaine);
// Affichage de la chaîne formatée
return 0;
}
La fonction sprintf() permet de formater des chaînes de caractères et de les stocker dans un tableau. Cela est utile lorsqu’on veut générer des chaînes avant de les écrire dans un fichier ou les afficher.
Lecture formatée en C avec
De manière similaire aux fonctions d’écriture, les fonctions de lecture formatées permettent de lire des données en fonction d’un format donné.
- scanf() :Lit des données à partir de l’entrée standard.
- fscanf(FILE *stream, …) :Lit des données à partir d’un fichier.
- sscanf(const char *str, …) :Lit des données à partir d’une chaîne de caractères.
La lecture d’un fichier peut être effectuée caractère par caractère avec fgetc() ou ligne par ligne avec fgets().
Caractères : Entrées et sorties en C
Les fonctions suivantes sont utilisées pour lire ou écrire des caractères, un par un, depuis ou vers un flux.
Fonction | Description |
---|---|
fgetc() | Lit un caractère depuis un fichier |
fputc() | Écrit un caractère dans un fichier |
getchar() | Lit un caractère depuis l’entrée standard |
putchar() | Écrit un caractère vers la sortie standard |
Exemple :
int readWriteFileNotFormated(FILE *f) {
fseek(f, 0, SEEK_SET);
// Equivalent to rewind(f);
// GETS famille
printf("%c\n", fgetc(f));
char chaine[10];
// char* chaine;
fpos_t *pos = 0;
fgetpos(f, pos);
fgets(chaine, 10, f);
printf("%s\n", chaine);
fsetpos(f, pos);
printf("%c\n", getc(f));
// PUTS famille
int c = 91;
fputc(c, f);
char *chaine2 = "ALPHORM.com";
fputs(chaine2, f);
putc(c, f);
putchar(c);
puts(chaine2);
return 0;
}
- Exemple d’exécution sur Eclipse
Entrées/sorties sans formatage en C
Les fonctions fread() et fwrite() sont utilisées pour lire et écrire des blocs de données brutes, sans traitement de format.
- fread(void *ptr, size_t size, size_t nmemb, FILE *stream) :Lit des blocs de données depuis un fichier.
- fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) :Écrit des blocs de données dans un fichier.
Exemple d’utilisation :
fwrite(&variable, sizeof(variable), 1,
fichier); // Écriture d'un bloc de données
Accès et opérations sur fichiers C
Les opérations sur les fichiers incluent l’ouverture, la fermeture, la suppression, et le renommage de fichiers.
- fopen(const char *filename, const char *mode) :Ouvre un fichier dans un mode spécifié (lecture, écriture, etc.).
- fclose(FILE *stream) :Ferme un fichier ouvert.
- remove(const char *filename) :Supprime un fichier du système.
- rename(const char *oldname, const char *newname) :Renomme un fichier.
Exemple de code : Création et ouverture d’un fichier
#include
#include
#include
#define debug 1
int writeNameAndFirstnameInFile(FILE *f, char *dest);
int readWriteFileNotFormated(FILE *f);
typedef struct personne_s {
char nom[10];
char prenom[10];
int age;
} personne;
int writeNameAndFirstnameInFile(FILE *f, char *dest) {
char nom[100];
char prenom[100];
scanf("%s %s", nom, prenom);
sprintf(dest, "Bienvenudanslaformationde%sen%s", nom, prenom);
if (f) {
fputs(dest, f);
puts(dest);
}
return 0;
}
int main(void) {
setbuf(stdout, NULL);
FILE *fp = fopen("test.txt", "w+");
char dest[100];
writeNameAndFirstnameInFile(fp, dest);
return 0;
}
L’ouverture d’un fichier en C se fait avec la fonction fopen(). Si le fichier n’existe pas et que nous spécifions un mode de création (par exemple « w » ou « a »), il sera automatiquement créé.
- Exemple d’exécution sur Eclipse :
Fichier non ouvert : Si fopen() retourne NULL, cela signifie que l’ouverture du fichier a échoué. Utilisez perror() pour afficher une erreur détaillée.
Mode incorrect : Utiliser un mode comme « r » pour un fichier inexistant provoquera une erreur.
Manipulation du pointeur de fichier C
Les fonctions suivantes permettent de manipuler le pointeur dans un fichier, c’est-à-dire la position courante où la prochaine lecture ou écriture aura lieu.
- fseek(FILE *stream, long offset, int whence) :Déplace le pointeur de fichier à une nouvelle position.
- ftell(FILE *stream) :Renvoie la position courante du pointeur dans le fichier.
- rewind(FILE *stream) :Réinitialise le pointeur au début du fichier.
- Exemple de code d’Utilisation de ftell et fseek :
int main(void) {
setbuf(stdout, NULL);
FILE *fp = fopen("test.txt", "w+");
char dest[100];
writeNameAndFirstnameInFile(fp, dest);
fseek(fp, 0, SEEK_END);
long taille = ftell(fp);
printf("taille fichier:%ld", taille);
fclose(fp);
return 0;
}
- Exemple d’exécution sur Eclipse :
Gestion des erreurs d'I/O en C
Les erreurs de manipulation de fichiers peuvent être détectées et gérées avec les fonctions perror() et ferror(). Cela permet d’afficher des messages d’erreur précis en fonction du contexte.
- ferror(FILE *stream) :Vérifie s’il y a eu une erreur lors d’une opération sur le fichier.
- perror(const char *message) :Affiche un message d’erreur correspondant à la dernière erreur rencontrée.
- Exemple de code d’Utilisation :
#include
int main() {
FILE *fichier = fopen("mon_fichier_inexistant.txt", "r");
if (fichier == NULL) {
perror("Erreur lors de l'ouverture du fichier");
return 1;
}
// Lecture du fichier
if (ferror(fichier)) {
perror("Erreur pendant la lecture");
}
fclose(fichier);
return 0;
}
- Exemple d’exécution sur Eclipse
Exemple de code : Entrée/sortie en C
Le code suivant met en œuvre différentes techniques pour lire et écrire dans des fichiers, gérer les erreurs et manipuler des données formatées et non formatées, ainsi que des structures de données en C. C’est un bon exemple pour illustrer les bases de la gestion des fichiers et des flux en C, tout en permettant de comprendre comment formater les données et manipuler des fichiers de manière efficace.
#include
#include
#include
#define debug 1
int writeNameAndFirstnameInFile(FILE *f, char *dest);
int readWriteFileNotFormated(FILE *f);
int readWriteFileFormated(FILE *f);
int readWriteDataFile();
typedef struct personne_s {
// char nom[10];
char prenom[10];
// int age;
} personne;
int writeNameAndFirstnameInFile(FILE *f, char *dest) {
char prenom[100];
scanf("%s", prenom);
sprintf(dest, "Bienvenue chez %s", prenom);
if (f) {
fputs(dest, f);
#if (debug == 1)
puts(dest);
if (ferror(f)) {
printf("Error in writting on the file: %d\n", errno);
perror("Debug");
return -1;
}
#endif
}
return 0;
}
int readWriteFileNotFormated(FILE *f) {
fseek(f, 0, SEEK_SET);
// Equivalent to rewind(f);
// GETS famille
printf("%c\n", fgetc(f));
char chaine[10];
// char* chaine;
fpos_t *pos = 0;
fgetpos(f, pos);
fgets(chaine, 10, f);
printf("%s\n", chaine);
fsetpos(f, pos);
printf("%c\n", getc(f));
// PUTS famille
int c = 91;
fputc(c, f);
char *chaine2 = "Alphorm.com";
fputs(chaine2, f);
putc(c, f);
putchar(c);
puts(chaine2);
return 0;
}
int readWriteFileFormated(FILE *f) {
fseek(f, 0, SEEK_END);
fputs("\n", f);
char dest[100];
char prenom[10] = "PRENOM";
sprintf(dest, "Bienvenue chez %s", prenom);
printf("%s\n", dest);
fprintf(f, "%s %s %s", "Bienvenue", "chez", prenom);
char str1[10], str2[10], str3[10], str4[10];
rewind(f);
fscanf(f, "%s %s %s %s", str1, str2, str3, str4);
puts(str1);
puts(str2);
puts(str3);
puts(str4);
char semaine[20], mois[20], date[100];
int jour, annee;
strcpy(date, "Lundi 12 décembre 2028");
sscanf(date, "%s %d %s %d", semaine, &jour, mois, &annee);
printf("%d %s %d = %s\n", jour, mois, annee, semaine);
return 0;
}
int readWriteDataFile() {
FILE *fRWDATA = fopen("fRWDATA", "w+");
int i;
personne s1;
for (i = 0; i < 3; i++) {
// sprintf(s1.nom,"%s %d","NOM",i);
sprintf(s1.prenom, "%s %d", "PRENOM", i);
int rtn = fwrite(&s1, sizeof(s1), 1, fRWDATA);
printf("Taille écrite:%d\n", rtn);
}
fseek(fRWDATA, 0, SEEK_SET);
// rewind(fRWDATA);
for (i = 0; i < 3; i++) {
personne stemp;
int rtn = fread(&stemp, sizeof(stemp), 1, fRWDATA);
printf("Taille lue:%d\n", rtn);
printf("Structure lue:,%s\n", stemp.prenom);
}
return 0;
}
int main(void) {
setbuf(stdout, NULL);
FILE *fp = fopen("test.txt", "w+");
char dest[100];
writeNameAndFirstnameInFile(fp, dest);
// readWriteFileNotFormated(fp);
// readWriteFileFormated(fp);
// readWriteDataFile();
fseek(fp, 0, SEEK_END);
long taille = ftell(fp);
printf("taille fichier:%ld", taille);
fclose(fp);
return 0;
}
Conclusion sur les E/S en C
Ce chapitre a couvert en profondeur les fonctions de gestion des entrées/sorties en C. Grâce à la compréhension des bibliothèques comme <stdio.h>, vous pouvez désormais manipuler efficacement les fichiers, gérer les entrées/sorties formatées et non formatées, et éviter les erreurs courantes.
Formez-vous gratuitement avec Alphorm !
Maîtrisez les compétences clés en IT grâce à nos formations gratuites et accélérez votre carrière dès aujourd'hui.
FAQ
Quelles sont les principales fonctions d'entrée/sortie en C ?
Comment manipuler les fichiers en C avec stdio.h ?
Quels types prédéfinis sont utilisés dans stdio.h ?
Quelles erreurs fréquentes sont associées aux entrées/sorties en C ?
Comment lire et écrire des caractères individuels en C ?
Conclusion
En maîtrisant les fonctions de stdio.h, vous pouvez manipuler efficacement les fichiers et les flux en C. Quelle est la prochaine étape dans votre exploration du langage C ?