NB, les entrées/sorties sur un fichier binaire ne seront pas traitées dans le cadre de la mise à niveau. Rappelons qu'un fichier texte est un fichier qui est lisible, il peut être édité dans votre éditeur de texte.
Lorsque vous voulez obtenir des informations sur le fichier, vous pouvez utiliser la commande file, pour un fichier exécutable vous obtiendrez executable, un fichier binaire data et un fichier texte text
> file donnees.bin donnees.bin: data > file donnees.txt donnees.txt: ASCII text > file lignes lignes: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), not stripped >
Ouverture d'un fichier
La fonction FILE *fopen(char *nomfic, char *mode) ouvre le fichier dont le nom est donné comme premier argument, selon le mode d'ouverture précisé (w = écriture, r = lecture, a = ajout en fin de fichier) et l'assigne à un flux, i.e. à une variable de type FILE *.
Dans le programme ci-dessous, nom_fic est une chaîne de caractères qui contient le nom du fichier à ouvrir, et fic est une variable de type FILE *.
// ouverture du fichier fic = fopen(nom_fic, "r"); // ouvrir en lecture if(fic == NULL){ printf("Impossible d'ouvrir le fichier %s\n", nom_fic); exit(1); } printf(".............. Ouverture du fichier %s\n", nom_fic);
Fermeture d'un fichier
// fermeture du fichier if(fclose(fic) == EOF){ printf("Probleme de fermeture du fichier %s", nom_fic); exit(1); } printf(".............. Fermeture du fichier %s\n", nom_fic);
Lecture des données d'un fichier
fgets
La fonction char *fgets(char *chaine, int max, FILE *fichier) lit une chaîne de caractères sur le fluxfichier et la stocke dans la chaîne chaine. Elle lit au maximum max - 1 caractères, elle s'arrête dès qu'elle rencontre un caractère de passage à la ligne et place un \0 à la fin de la chaîne. Lorsqu'elle rencontre la fin de fichier, elle retourne la chaîne NULL.
Prenons un programme qui affiche le contenu d'un fichier et compte le nombre de lignes de ce fichier :
#include <stdio.h> #include <string.h> #include <stdlib.h> void verif_et_recup_arg(int nb, char *arguments[], int nb_souhaite, char *chaine) { if(nb != nb_souhaite){ printf("Usage : lignes nom_fichier\n"); exit(1); } strcpy(chaine, arguments[1]); } int main(int argc, char *argv[]) { FILE *fic; int nb_lignes; char ligne_lue[512]; char nom_fic[255]; verif_et_recup_arg(argc, argv, 2, nom_fic); // ouverture du fichier fic = fopen(nom_fic, "r"); // ouvrir en lecture if(fic == NULL){ printf("Impossible d'ouvrir le fichier %s\n", nom_fic); exit(1); } printf(".............. Ouverture du fichier %s\n", nom_fic); // compter et afficher les lignes du fichier nb_lignes = 0; while(fgets(ligne_lue, 512, fic) != NULL){ printf("\t%s", ligne_lue); nb_lignes++; } printf("le fichier %s comporte %d lignes\n", nom_fic, nb_lignes); // fermeture du fichier if(fclose(fic) == EOF) { printf("Probleme de fermeture du fichier %s", nom_fic); exit(1); } printf(".............. Fermeture du fichier %s\n", nom_fic); return 0; }
NB : le \n n'est pas placé dans le printf("\t%s", ligne_lue); qui affiche le contenu de la variable ligne_luecar fgets stocke le caractère de retour à la ligne quand il le lit. Si nous avions demandé printf("\t%s\n", ligne_lue);. Nous aurions obtenu sur la console une ligne blanche entre chaque ligne du fichier.
> ls donnees.txt lignes.c > more donnees.txt une chaine sur la 1ere ligne une autre chaine sur la 2eme ligne 14 3.5 une chaine sur la 5eme ligne derniere ligne avant la fin > gcc -Wall lignes.c -o lignes > ./lignes Usage : lignes nom_fichier > ./lignes donnee.txt Impossible d'ouvrir le fichier donnee.txt > ./lignes donnees.txt .............. Ouverture du fichier donnees.txt une chaine sur la 1ere ligne une autre chaine sur la 2eme ligne 14 3.5 une chaine sur la 5eme ligne derniere ligne avant la finle fichier donnees.txt comporte 6 lignes .............. Fermeture du fichier donnees.txt >
Nous avons précisé que fgets lit au maximum le nombre de caractères - 1 précisé en argument. Lorsqu'on souhaite lire une ligne entière, on donne un maximum élevé. Si dans notre exemple, nous avions écrit : fgets(ligne_lue, 10,fic) à la place de fgets(ligne_lue, 512, fic), nous aurions obtenu le résultat ci-dessous :
> ./lignes donnees.txt .............. Ouverture du fichier donnees.txt une chain e sur la 1ere lign e une autre chaine s ur la 2em e ligne 14 3.5 une chain e sur la 5eme lign e derniere ligne ava nt la finle fichier donnees.txt comporte 17 lignes .............. Fermeture du fichier donnees.txt >
fscanf
La fonction fscanf(FILE *fichier, char *format, adr_var_1, adr_var_2, ...) prend comme premier argument le flux dans lequel elle doit lire et stocke les données lues selon le format défini par la chaîne format dans les variables adr_var_ passées par adresse.
Le programme ci-dessous utilise la fonction scanf pour stocker dans des variables les informations d'un fichier annuaire qui comporte sur chaque ligne un nom, un prénom, le numéro de téléphone et l'adresse mail d'une personne. NB : on suppose que le nom de la personne ne comporte pas d'espace.
#include <stdio.h> #include <string.h> #include <stdlib.h> void verif_et_recup_arg(int nb, char *arguments[], int nb_souhaite, char *chaine) { if(nb != nb_souhaite){ printf("Usage : annuaire nom_fichier\n"); exit(1); } strcpy(chaine, arguments[1]); } int main(int argc, char *argv[]) { FILE *fic; int nb_lignes, t1, t2, t3, t4, t5; char nom_fic[255], nom[255], prenom[255], mail[255]; verif_et_recup_arg(argc, argv, 2, nom_fic); // ouverture du fichier fic = fopen(nom_fic, "r"); // ouvrir en lecture if(fic == NULL){ printf("Impossible d'ouvrir le fichier %s\n", nom_fic); exit(1); } printf(".............. Ouverture du fichier %s\n\n", nom_fic); // recuperer les donnees de l'annuaire nb_lignes = 0; while(fscanf(fic, "%s %s %d %d %d %d %d %s", nom, prenom,\ &t1, &t2, &t3, &t4, &t5, mail) != EOF){ printf("\tnom = %s\n \tprenom = %s\n \ttel = %.2d %.2d %.2d %.2d %.2d\n \tmail = %s\n\n",\ nom, prenom, t1, t2, t3, t4, t5, mail); nb_lignes++; } printf("le fichier %s comporte %d lignes\n", nom_fic, nb_lignes); // fermeture du fichier if(fclose(fic) == EOF){ printf("Probleme de fermeture du fichier %s", nom_fic); exit(1); } printf(".............. Fermeture du fichier %s\n", nom_fic); return 0; }
> more annuaire.txt Contensin Magali 04 91 11 36 13 contensin@cmi.univ-mrs.fr Alessandra Denis 04 91 11 36 13 alessand@club-internet.fr Ifrah Sandrine 04 91 11 35 21 ifrah@cmi.univ-mrs.fr > gcc -Wall annuaire.c -o annuaire > ./annuaire annuaire.txt .............. Ouverture du fichier annuaire.txt nom = Contensin prenom = Magali tel = 04 91 11 36 13 mail = contensin@cmi.univ-mrs.fr nom = Alessandra prenom = Denis tel = 04 91 11 36 13 mail = alessand@club-internet.fr nom = Ifrah prenom = Sandrine tel = 04 91 11 35 21 mail = ifrah@cmi.univ-mrs.fr le fichier annuaire.txt comporte 3 lignes .............. Fermeture du fichier annuaire.txt >
Écriture de données dans un fichier
fputs
La fonction int fputs(char *chaine, FILE *fic) écrit la chaîne de caractères chaine sur le flux fic. Elle retourne le dernier caractère de la chaîne en cas de succès (EOF en cas d'erreur).#include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *fic; int nb_lignes; char ligne_lue[512]; // ouverture du fichier fic = fopen("resultat.txt", "w"); // ouvrir en ecriture if(fic == NULL){ printf("Impossible d'ouvrir le fichier resultat.txt\n"); exit(1); } do{ fgets(ligne_lue, 512, stdin); fputs(ligne_lue, fic); } while(strcmp(ligne_lue, "FIN\n") != 0); // fermeture du fichier if(fclose(fic) == EOF) { printf("Probleme de fermeture du fichier resultat.txt\n"); exit(1); } printf("les donnees ont ete stockees dans resultat.txt\n"); return 0; }
> gcc ecritligne.c -o ecrit > ./ecrit FIN les donnees ont ete stockees dans resultat.txt > gcc ecritligne.c -o ecrit > ./ecrit premiere ligne entree sur la console ceci est la deuxieme ligne encore une ligne de test FIN les donnees ont ete stockees dans resultat.txt > more resultat.txt premiere ligne entree sur la console ceci est la deuxieme ligne encore une ligne de test FIN >
fprintf
La fonction int fprintf(FILE *fic, char *format, var_1, var_2, ...) écrit les données var_ dans le flux fic en respectant le format spécifié par la chaîne format. Elle retourne le nombre de caractères écrits sur le flux.
Le programme ci-dessous ajoute une entrée dans l'annuaire :
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { FILE *fic; char nom_fic[255], nom[255], prenom[255], mail[255]; int t1, t2, t3, t4, t5; // stockage des donnees issues de la ligne de commandes if(argc != 10){ //10 car num. tel. = 5 blocs d'entiers printf("Usage : annuaire nom_fichier nom prenom tel mail\n"); exit(1); } strcpy(nom_fic, argv[1]); strcpy(nom, argv[2]); strcpy(prenom, argv[3]); strcpy(mail, argv[9]); t1 = atoi(argv[4]); t2 = atoi(argv[5]); t3 = atoi(argv[6]); t4 = atoi(argv[7]); t5 = atoi(argv[8]); // ouverture du fichier fic = fopen(argv[1], "a"); // ouvrir en ajout if(fic == NULL){ printf("Impossible d'ouvrir le fichier %s\n", nom_fic); exit(1); } // ajouter les donnees dans l'annuaire fprintf(fic, "\n%s %s %.2d %.2d %.2d %.2d %.2d %s", nom, prenom, t1, t2, t3, t4, t5, mail); // fermeture du fichier if(fclose(fic) == EOF){ printf("Probleme de fermeture du fichier %s", nom_fic); exit(1); } printf("Les informations ont ete stockees dans l'annuaire\n"); return 0; }
> gcc ecritannuaire.c -o ecrit > more annuaire.txt Contensin Magali 04 91 11 36 13 contensin@cmi.univ-mrs.fr Alessandra Denis 04 91 11 36 13 alessand@club-internet.fr Ifrah Sandrine 04 91 11 35 21 ifrah@cmi.univ-mrs.fr > ./ecrit Usage : annuaire nom_fichier nom prenom tel mail > ./ecrit annuaire.txt Dupond Georges 04 94 13 22 11 dupond@bidule.net Les informations ont ete stockees dans l'annuaire > more annuaire.txt Contensin Magali 04 91 11 36 13 contensin@cmi.univ-mrs.fr Alessandra Denis 04 91 11 36 13 alessand@club-internet.fr Ifrah Sandrine 04 91 11 35 21 ifrah@cmi.univ-mrs.fr Dupond Georges 04 94 13 22 11 dupond@bidule.net >
0 comments:
Post a Comment