Nous allons ici voir comment écrire dans un fichier, nous utiliserons deux fonctions différentes : fwrite et fprintf. La première de ces fonctions sert à écrire dans des fichiers binaires et la deuxième fait la même chose mais pour les fichiers textes (bien qu'on sache utiliser fwrite pour les fichiers textes mais c'est moins facile et clair que fprintf).
Ecrire dans un fichier de façon binaire entraine que ce fichier ne sera pas lisible par un utilisateur ouvrant ce fichier directement dans le bloc-note. Ce type de stockage sert à sauvegarder des données utiles pour un programme. Imaginez que vous utilisiez un programme qui sert à gérer une classe et que les élèves sont stockés dans un tableau de structure. Les structures en questions contiendront simplement le nom et le prénom de l'étudiant (c'est à titre d'exemple). Il se peut que vous n'ayez pas envie de réencoder tout les étudiants à chaque fois que vous fermez votre programme et que vous le réouvrez, vous allez donc sauvegarder le tableau de structures dans le fichier.
Pour tout cela, vous devrez utiliser la fonction fwrite qui permet l'écriture de données binaires dans un flux et comme les fichiers sont ouverts comme des flux, cela fonctionnera. La syntaxe de déclaration de cette fonction est la suivante :
Comme vous le voyez, cette fonction renvoit une valeur de type size_t, c'est en fait un variable de type entière qui signalera combien d'octets la fonction a écrit. La fonction fwrite prend 4 arguments. Le premier sera l'adresse de ce que nous voulons écrire, le deuxième sera la taille de la donnée à écrire, le troisième définira le nombre de fois que le programme écrira la donnée et le quatrième argument sera le flux dans lequel la donnée sera écrite.
Cela ne doit pas être clair comme cela, je vais donc faire un petit exemple. Le but de ce programme sera simplement d'écrire un tableau de structure dans un fichier. Ce tableau sera toujours le même étant donné que le programme ne fera que définir dans le code le tableau, sauvera ce tableau et quittera le programme. Tapez donc :
Nous commençons en déclarant une structure que l'on nommera etudiant qui contiendra le nom et le prénom d'un étudiant. Quand le programme entrera dans le main, il verra que l'on déclare un tableau de 2 etudiants et un pointeur vers un fichier. Nous ouvrons le fichier a.bin (qui sera créé si il n'existe pas) en mode wb donc écriture binaire.
Nous remplissons ensuite le tableau avec les données et nous écrivons ensuite le tableau dans le fichier. Comme je l'ai dit tantot, le premier argument de la fonction fwrite est la donnée à écrire, en l'occurence, le tableau, nous passons donc l'adresse du tableau comme premier argument. Le deuxième argument est la taille de la donnée. Ici c'est un tableau de deux structures, nous multiplions donc la taille de la structure par 2 pour obtenir la taille du tableau et nous faisons passer cette taille en paramètre. Le troisième argument est le nombre de fois que nous allons écrire le tableau, ici on ne désire ne l'écrire qu'une seule fois, on mettra donc 1 comme valeur. Enfin, nous spécifions que cette donnée sera à écrire dans le fichier f (le flux f). Ensuite, nous fermons le fichier.
Si nous regardons dans le dossier de notre programme, vous verrez le fichier a.bin qui a la taille de 256 octets. Ceci est déjà une bonne indication, effectivement, la structure contient deux champs de 64 octets, donc la taille d'une structure vaut 64 + 64, c'est à dire 128 octets, donc la taille du tableau était de 256 octets et le fichier fait cette taille, c'est déjà bon signe. Ensuite, si vous ouvrez a.bin avec un editeur hexa-décimal (sous Linux) ou le bloc note (sous windows car je pense que ca fonctionne), vous verrez apparaitre des caractères incompréhensibles et au milieu de ceux-ci Zick, Zack, Zock et Zuck. Les autres caractères sont en fait des crasses contenues dans les chaines de caractères des structures, pour ne pas les voir, il suffisait de faire unmemset avant la définition de leur valeur.
Vous voyez donc qu'il est très simple d'écrire une donnée quelconque dans un fichier, pour écrire des données de type de base tels que int, float ou autre, ne vous cassez pas la tête, c'est de la même façon, il suffit de faire passer l'adresse de la variable (&variable) en premier paramètre et la taille du type (sizeof(int) par exemple) en deuxième argument, le reste ne change pas.
Il y a un moment où écrire des données binaires c'est bien mais ce n'est pas assez, imaginez par exemple que vous vouliez écrire un fichier de log, vous n'allez pas sans cesse l'écrire en binaire ? Autant utiliser une fonction faite pour ca, vous utiliserez donc fprintf. Cette fonction se base sur la fonction printf, donc pour ce qui est de la façon d'utiliser la chaine de format, je vous conseille d'aller d'abord lire le cours sur printf car je ne réexpliquerai pas comment s'en servir ici. La syntaxe de déclaration defprintf est la suivante :
Comme vous le voyez, la fonction renvoie un nombre entier qui sera, comme dans toute fonction d'écriture, le nombre d'octet écrit. Le premier argument de la fonction est le flux dans lequel nous écrirons les données, autrement dit, le pointeur vers le fichier vu que ceux-ci sont ouverts comme des flux. Les arguments suivants seront la chaine de format et les données à écrire, pour plus d'informations, lisez le cours sur printf.
Le programme suivant va simuler l'écriture d'un fichier de log, vous allez voir c'est assez simple :
Ici, nous commençons par déclarer deux variables entières a et b. Nous déclarons également un pointeur de fichier qui récupèrera l'adresse renvoyée par la fonction fopen. Grace à cette dernière, nous ouvrons le fichier log.txt en ajout, donc tout ce que nous écrirons dans ce fichier s'écrira à la fin de celui-ci. Ce fichier sera créé si il n'existait pas à l'ouverture.
Nous utilisons la fonction fprintf pour écrire une phrase dans le fichier dont l'adresse est contenue dans le pointeur f. Comme vous le voyez, nous utilisons la fonction fprintf de la même manière que nous utilisons printf sauf que nous passons en premier paramètre l'adresse du flux dans lequel doit être écrit la donnée.
Nous demandons ensuite d'entrer la valeur de a que nous récupérons grace au scanf. vous voyez qu'ensuite, nous écrivons une phrase de log comprenant la valeur de la variable a, cela vous démontre que nous pouvons utiliser les variables tout comme dans le printf. Nous faisons de même pour la variable b et nous écrivons même dans le fichier la valeur de la somme de ces deux variables avant d'écrire que le programme se termine. Si vous exécutez votre programme, vous verrez un fichier dans votre répertoire de travail qui contiendra les données écrites.
Ecrire dans des fichiers binaires
Ecrire dans un fichier de façon binaire entraine que ce fichier ne sera pas lisible par un utilisateur ouvrant ce fichier directement dans le bloc-note. Ce type de stockage sert à sauvegarder des données utiles pour un programme. Imaginez que vous utilisiez un programme qui sert à gérer une classe et que les élèves sont stockés dans un tableau de structure. Les structures en questions contiendront simplement le nom et le prénom de l'étudiant (c'est à titre d'exemple). Il se peut que vous n'ayez pas envie de réencoder tout les étudiants à chaque fois que vous fermez votre programme et que vous le réouvrez, vous allez donc sauvegarder le tableau de structures dans le fichier.
Pour tout cela, vous devrez utiliser la fonction fwrite qui permet l'écriture de données binaires dans un flux et comme les fichiers sont ouverts comme des flux, cela fonctionnera. La syntaxe de déclaration de cette fonction est la suivante :
- size_t fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream);
Comme vous le voyez, cette fonction renvoit une valeur de type size_t, c'est en fait un variable de type entière qui signalera combien d'octets la fonction a écrit. La fonction fwrite prend 4 arguments. Le premier sera l'adresse de ce que nous voulons écrire, le deuxième sera la taille de la donnée à écrire, le troisième définira le nombre de fois que le programme écrira la donnée et le quatrième argument sera le flux dans lequel la donnée sera écrite.
Cela ne doit pas être clair comme cela, je vais donc faire un petit exemple. Le but de ce programme sera simplement d'écrire un tableau de structure dans un fichier. Ce tableau sera toujours le même étant donné que le programme ne fera que définir dans le code le tableau, sauvera ce tableau et quittera le programme. Tapez donc :
- #include <stdio.h>
- #include <string.h>
- typedef struct {
- char nom[64];
- char prenom[64];
- } etudiant;
- int main() {
- etudiant e[2];
- FILE *f = fopen("a.bin", "wb");
- strcpy(e[0].nom, "Zick");
- strcpy(e[0].prenom, "Zack");
- strcpy(e[1].nom, "Zock");
- strcpy(e[1].prenom, "Zuck");
- fwrite(e, 2 * sizeof(etudiant), 1, f);
- fclose(f);
- return 0;
- }
Nous commençons en déclarant une structure que l'on nommera etudiant qui contiendra le nom et le prénom d'un étudiant. Quand le programme entrera dans le main, il verra que l'on déclare un tableau de 2 etudiants et un pointeur vers un fichier. Nous ouvrons le fichier a.bin (qui sera créé si il n'existe pas) en mode wb donc écriture binaire.
Nous remplissons ensuite le tableau avec les données et nous écrivons ensuite le tableau dans le fichier. Comme je l'ai dit tantot, le premier argument de la fonction fwrite est la donnée à écrire, en l'occurence, le tableau, nous passons donc l'adresse du tableau comme premier argument. Le deuxième argument est la taille de la donnée. Ici c'est un tableau de deux structures, nous multiplions donc la taille de la structure par 2 pour obtenir la taille du tableau et nous faisons passer cette taille en paramètre. Le troisième argument est le nombre de fois que nous allons écrire le tableau, ici on ne désire ne l'écrire qu'une seule fois, on mettra donc 1 comme valeur. Enfin, nous spécifions que cette donnée sera à écrire dans le fichier f (le flux f). Ensuite, nous fermons le fichier.
Si nous regardons dans le dossier de notre programme, vous verrez le fichier a.bin qui a la taille de 256 octets. Ceci est déjà une bonne indication, effectivement, la structure contient deux champs de 64 octets, donc la taille d'une structure vaut 64 + 64, c'est à dire 128 octets, donc la taille du tableau était de 256 octets et le fichier fait cette taille, c'est déjà bon signe. Ensuite, si vous ouvrez a.bin avec un editeur hexa-décimal (sous Linux) ou le bloc note (sous windows car je pense que ca fonctionne), vous verrez apparaitre des caractères incompréhensibles et au milieu de ceux-ci Zick, Zack, Zock et Zuck. Les autres caractères sont en fait des crasses contenues dans les chaines de caractères des structures, pour ne pas les voir, il suffisait de faire unmemset avant la définition de leur valeur.
Vous voyez donc qu'il est très simple d'écrire une donnée quelconque dans un fichier, pour écrire des données de type de base tels que int, float ou autre, ne vous cassez pas la tête, c'est de la même façon, il suffit de faire passer l'adresse de la variable (&variable) en premier paramètre et la taille du type (sizeof(int) par exemple) en deuxième argument, le reste ne change pas.
Ecrire dans des fichiers textes
Il y a un moment où écrire des données binaires c'est bien mais ce n'est pas assez, imaginez par exemple que vous vouliez écrire un fichier de log, vous n'allez pas sans cesse l'écrire en binaire ? Autant utiliser une fonction faite pour ca, vous utiliserez donc fprintf. Cette fonction se base sur la fonction printf, donc pour ce qui est de la façon d'utiliser la chaine de format, je vous conseille d'aller d'abord lire le cours sur printf car je ne réexpliquerai pas comment s'en servir ici. La syntaxe de déclaration defprintf est la suivante :
- int fprintf (FILE *stream, const char *format, ...);
Comme vous le voyez, la fonction renvoie un nombre entier qui sera, comme dans toute fonction d'écriture, le nombre d'octet écrit. Le premier argument de la fonction est le flux dans lequel nous écrirons les données, autrement dit, le pointeur vers le fichier vu que ceux-ci sont ouverts comme des flux. Les arguments suivants seront la chaine de format et les données à écrire, pour plus d'informations, lisez le cours sur printf.
Le programme suivant va simuler l'écriture d'un fichier de log, vous allez voir c'est assez simple :
- #include <stdio.h>
- #include <string.h>
- int main() {
- int a = 0;
- int b = 0;
- FILE *f = fopen("log.txt", "a");
- fprintf (f, "Le programme a été ouvert\n");
- printf ("Veuillez entrer a :");
- scanf ("%d", &a);
- fprintf (f, "L'utilisateur a entré la valeur %d pour a\n", a);
- printf ("Veuillez entrer b :");
- scanf ("%d", &b);
- fprintf (f, "L'utilisateur a entré la valeur %d pour b\n", b);
- fprintf (f, "La somme de %d et %d est donc %d\n", a, b, a+b);
- fprintf (f, "Le programme se termine\n");
- fclose(f);
- return 0;
- }
Ici, nous commençons par déclarer deux variables entières a et b. Nous déclarons également un pointeur de fichier qui récupèrera l'adresse renvoyée par la fonction fopen. Grace à cette dernière, nous ouvrons le fichier log.txt en ajout, donc tout ce que nous écrirons dans ce fichier s'écrira à la fin de celui-ci. Ce fichier sera créé si il n'existait pas à l'ouverture.
Nous utilisons la fonction fprintf pour écrire une phrase dans le fichier dont l'adresse est contenue dans le pointeur f. Comme vous le voyez, nous utilisons la fonction fprintf de la même manière que nous utilisons printf sauf que nous passons en premier paramètre l'adresse du flux dans lequel doit être écrit la donnée.
Nous demandons ensuite d'entrer la valeur de a que nous récupérons grace au scanf. vous voyez qu'ensuite, nous écrivons une phrase de log comprenant la valeur de la variable a, cela vous démontre que nous pouvons utiliser les variables tout comme dans le printf. Nous faisons de même pour la variable b et nous écrivons même dans le fichier la valeur de la somme de ces deux variables avant d'écrire que le programme se termine. Si vous exécutez votre programme, vous verrez un fichier dans votre répertoire de travail qui contiendra les données écrites.
0 comments:
Post a Comment