Ecriture dans un fichier
aure2015
Messages postés
93
Date d'inscription
Statut
Membre
Dernière intervention
-
[Dal] Messages postés 6205 Date d'inscription Statut Contributeur Dernière intervention -
[Dal] Messages postés 6205 Date d'inscription Statut Contributeur Dernière intervention -
Bonjour à tous!
Je vous explique mon petit problème, j'ai une ligne à modifier dans un fichier! Hors malgré mon ouverture r+, ça ne fonctionne pas et je ne comprends pas pourquoi! Ca compile, ça ne me renvoie pas d'erreur mais ça ne modifie pas le fichier comme il devrait! ( Je compile sous Unix).
Merci d'avance!
Voici le code:
Je vous explique mon petit problème, j'ai une ligne à modifier dans un fichier! Hors malgré mon ouverture r+, ça ne fonctionne pas et je ne comprends pas pourquoi! Ca compile, ça ne me renvoie pas d'erreur mais ça ne modifie pas le fichier comme il devrait! ( Je compile sous Unix).
Merci d'avance!
Voici le code:
void RecupCom( ) { COMMANDES Com; FILE *Fichier; int Taille; Fichier=fopen("Commandes.dat","rb"); if(Fichier!=NULL) { fread(&Com,sizeof(COMMANDES),1,Fichier); while (!feof(Fichier)) { Trace("%s\t%d\n",Com.Nom,Com.Valide); fread(&Com,sizeof(COMMANDES),1,Fichier); } fclose(Fichier); Fichier=fopen("Commandes.dat","r+"); fread(&Com,sizeof(COMMANDES),1,Fichier); Taille=0; while (!feof(Fichier)) { if(Com.Valide==2) { // fseek(Fichier,(-sizeof(COMMANDES)),SEEK_CUR) if(fseek(Fichier,(Taille*sizeof(COMMANDES)),SEEK_SET)!=0) Trace("Erreur"); Com.Valide=1; Trace("Boucle modif"); if(fwrite(&Com,sizeof(COMMANDES),1,Fichier)<0) Trace("Erreur ecriture"); } Taille++; fread(&Com,sizeof(COMMANDES),1,Fichier); } Trace("Apres modif\n"); fclose(Fichier); fopen("Commandes.dat","rb"); fread(&Com,sizeof(COMMANDES),1,Fichier); while (!feof(Fichier)) { Trace("%s\t%d\n",Com.Nom,Com.Valide); fread(&Com,sizeof(COMMANDES),1,Fichier); } fclose(Fichier); } }
A voir également:
- Ecriture dans un fichier
- Fichier bin - Guide
- Comment réduire la taille d'un fichier - Guide
- Comment ouvrir un fichier epub ? - Guide
- Fichier rar - Guide
- Fichier .dat - Guide
2 réponses
Salut aure2015,
C'est un peu difficile le programme n'étant pas un exemple complet permettant de tester et je ne comprends pas trop ce qu'est le type COMMANDES, qui a l'air d'être un struct,... cependant il semble que tu lises le contenu d'un fichier binaire dans l'espace mémoire alloué à ce struct, puisque tu spécifies "rb" lorsque tu l'ouvres en lecture.
Par contre, lorsque tu ouvres le fichier en lecture/écriture, tu ne spécifies plus que ton fichier est binaire.
Essaye donc de passer ""r+b" ou "rb+" au lieu de seulement "r+" pour voir si cela arrange les choses :-)
Dal
C'est un peu difficile le programme n'étant pas un exemple complet permettant de tester et je ne comprends pas trop ce qu'est le type COMMANDES, qui a l'air d'être un struct,... cependant il semble que tu lises le contenu d'un fichier binaire dans l'espace mémoire alloué à ce struct, puisque tu spécifies "rb" lorsque tu l'ouvres en lecture.
Par contre, lorsque tu ouvres le fichier en lecture/écriture, tu ne spécifies plus que ton fichier est binaire.
Essaye donc de passer ""r+b" ou "rb+" au lieu de seulement "r+" pour voir si cela arrange les choses :-)
Dal
Je vais remettre des fonctions un peu plus clairement, c'est vrai que ce n'est pas top pour le moment! J'y avais déjà pensé mais rien ne change!
Merci pour l'aide quand même!
Le code:
Merci pour l'aide quand même!
Le code:
typedef struct { int Valide; char Nom[50]; } COMMANDES; void Ajout(char *Com) { Trace("AjoutCommande commence"); FILE *Fichier; COMMANDES New; if ((Fichier = fopen("Commandes.dat","a")) == NULL) { Trace("Erreur de l'ouverture du Fichier (exit Personnel)"); exit(1); } strcpy(New.Nom,Com; New.Valide=1; fwrite(&New,sizeof(COMMANDES),1,Fichier); fclose(Fichier); Trace("Sortie Ajout"); } void Modification () { COMMANDES Com; FILE *Fichier; int Taille; if((Fichier=fopen("Commandes.dat","r+"))!=NULL) { Taille=0; fflush(stdin); fread(&Com,sizeof(COMMANDES),1,Fichier); while (!feof(Fichier)) { Trace("Avant: %s\t%d\n",Com.Nom,Com.Valide); if(Com.Valide==2) { if(fseek(Fichier,(-sizeof(COMMANDES)),SEEK_CUR)!=0) Trace("Erreur"); Com.Valide=1; Trace("Boucle modif"); if(fwrite(&Com,sizeof(COMMANDES),1,Fichier)<=0) Trace("Erreur ecriture"); Trace("Après Modif: %s\t%d\n",Com.Nom,Com.Valide); } Taille++; fread(&Com,sizeof(COMMANDES),1,Fichier); } fclose(Fichier); } else { Fichier=fopen("Commandes.dat","w"); fclose(Fichier); } } void AfficherCommande () { COMMANDES Com; FILE *Fichier; Fichier=fopen("Commandes.dat","rb"); if(Fichier!=NULL) { fread(&Com,sizeof(COMMANDES),1,Fichier); while (!feof(Fichier)) { Trace("%s\t%d\n",Com.Nom,Com.Valide); fread(&Com,sizeof(COMMANDES),1,Fichier); } fclose(Fichier); } }
Dans la fonction Ajout(), il manque une parenthèse fermante à strcpy. Je suppose que c'est une erreur de copie-coller, car cette erreur de syntaxe empêcherait la compilation. Aussi, tu ne devrais pas utiliser strcpy(), mais strncpy().
Dans la fonction Modification(), tu fais
Dans la fonction Modification(), tu fais
Ta fonction Ajout() met le champ Valide à 1. Lorsque tu exécutes ta fonction Modification(), tu cherches des champs Valide égaux à 2, pour les mettre à 1. S'il n'y a pas de champs Valide avec une valeur de 2, c'est normal que rien ne soit modifié.
Si, en revanche, tu changes la fonction Modification pour changer les 1 en 2, le code suivant a l'air de fonctionner chez moi :
J'ai un mis getchar() entre l'Ajout et la Modification, pour avoir le temps de faire un hexdump du fichier sur un autre terminal et vérifier son contenu brut entre les deux opérations.
Après Ajout() :
après Modification() :
On voit bien que seul le premier octet est modifié, qui correspond à l'octet de poids faible du int.
Dal
Dans la fonction Modification(), tu fais
fflush(stdin);, que tu devrais retirer, car en C standard fflush() n'est conçu pour travailler que sur des flux ouverts en écriture (le comportement de cette instruction est indéfini avec stdin en argument).
Dans la fonction Modification(), tu fais
if(fwrite(&Com,sizeof(COMMANDES),1,Fichier)<=0), ce qui n'a pas trop de sens car fwrite retourne un type size_t qui est un entier non signé.
Ta fonction Ajout() met le champ Valide à 1. Lorsque tu exécutes ta fonction Modification(), tu cherches des champs Valide égaux à 2, pour les mettre à 1. S'il n'y a pas de champs Valide avec une valeur de 2, c'est normal que rien ne soit modifié.
Si, en revanche, tu changes la fonction Modification pour changer les 1 en 2, le code suivant a l'air de fonctionner chez moi :
$ cat 35156345.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #define Trace printf typedef struct { int Valide; char Nom[50]; } COMMANDES; void Ajout(char *Com) { Trace("AjoutCommande commence\n"); FILE *Fichier; COMMANDES New; if ((Fichier = fopen("Commandes.dat","a")) == NULL) { Trace("Erreur de l'ouverture du Fichier (exit Personnel)\n"); exit(1); } strcpy(New.Nom,Com); New.Valide=1; fwrite(&New,sizeof(COMMANDES),1,Fichier); fclose(Fichier); Trace("Sortie Ajout\n"); } void Modification(void) { COMMANDES Com; FILE *Fichier; int Taille; int written; if((Fichier=fopen("Commandes.dat","r+"))!=NULL) { Taille=0; fread(&Com,sizeof(COMMANDES),1,Fichier); while (!feof(Fichier)) { Trace("Avant: %s\t%d\n",Com.Nom,Com.Valide); if(Com.Valide==1) { if(fseek(Fichier,(-sizeof(COMMANDES)),SEEK_CUR)!=0) Trace("Erreur\n"); Com.Valide=2; Trace("Boucle modif\n"); written = fwrite(&Com,sizeof(COMMANDES),1,Fichier); if ( (written == 0) || (written != sizeof(COMMANDES)) ) Trace("Erreur ecriture\n"); Trace("Après Modif: %s\t%d\n",Com.Nom,Com.Valide); } Taille++; fread(&Com,sizeof(COMMANDES),1,Fichier); } fclose(Fichier); } else { Fichier=fopen("Commandes.dat","w"); fclose(Fichier); } } void AfficherCommande(void) { COMMANDES Com; FILE *Fichier; Fichier=fopen("Commandes.dat","rb"); if(Fichier!=NULL) { fread(&Com,sizeof(COMMANDES),1,Fichier); while (!feof(Fichier)) { Trace("%s\t%d\n",Com.Nom,Com.Valide); fread(&Com,sizeof(COMMANDES),1,Fichier); } fclose(Fichier); } } int main(void) { Ajout("toto"); AfficherCommande(); getchar(); Modification(); AfficherCommande(); return 0; }
$ rm Commandes.dat ; gcc -Wall 35156345.c $ ./a.out AjoutCommande commence Sortie Ajout toto 1 Avant: toto 1 Boucle modif Erreur ecriture Après Modif: toto 2 toto 2 $
J'ai un mis getchar() entre l'Ajout et la Modification, pour avoir le temps de faire un hexdump du fichier sur un autre terminal et vérifier son contenu brut entre les deux opérations.
Après Ajout() :
$ hexdump -C Commandes.dat 00000000 01 00 00 00 74 6f 74 6f 00 82 04 08 30 a9 72 b7 |....toto....0.r.| 00000010 00 00 00 00 bf 00 00 00 16 6f 5c b7 ff ff ff ff |.........o\.....| 00000020 be 93 90 bf f8 db 53 b7 43 22 56 b7 00 00 00 00 |......S.C"V.....| 00000030 48 30 b4 2c 01 00 00 00 |H0.,....| 00000038
après Modification() :
$ hexdump -C Commandes.dat 00000000 02 00 00 00 74 6f 74 6f 00 82 04 08 30 a9 72 b7 |....toto....0.r.| 00000010 00 00 00 00 bf 00 00 00 16 6f 5c b7 ff ff ff ff |.........o\.....| 00000020 be 93 90 bf f8 db 53 b7 43 22 56 b7 00 00 00 00 |......S.C"V.....| 00000030 48 30 b4 2c 01 00 00 00 |H0.,....| 00000038
On voit bien que seul le premier octet est modifié, qui correspond à l'octet de poids faible du int.
Dal