Forum Clubic

Modifier une structure dans un fichier c

bonjour a tous,

j’ai dans mon programme cette structure :
struct eleve
{
int idelv;
int valid;
char nom[10];
char prenom[10];
};

dans un partie de programme, j’écris cette structure dans un fichier avec différents nom et prénom … la variable idelv s’incrémente a chaque élève ajouter et la variable valide est toujours initialement à un. ce qui me donne dans mon fichier :

1
1
dupont
jean
2
1
dubois
pierre


cette partie fonctionne.
A présent je souhaite relire cette structure dans mon fichier affin de pouvoir modifier le caractère valid d’un élève en particulier pour obtenir par exemple: si je lui donne le nom dubois il me remplace le 1 par 0 :
1
1
dupont
jean
2
0<—
dubois
pierre


mais ce que j’ai fait le fonctionne pas … c’est ici que vôtre aide me serait utile. voila ce que j’ai:

FILE *f_in; // pointeur sur fichier
struct eleve ELV; // ELV pointe sur la structure eleve

char elv[10];

if ((f_in=fopen(ELEVE,"r+"))== NULL)
{
    fprintf(stderr, "nErreur: Impossible de lire le fichier %n",ELEVE);
    return (EXIT_FAILURE);
} // ouverture de mon fichier en lecture écriture

getchar();

printf("saisir le nom de l'eleve a supprimern");

gets(elv);
while(fscanf (f_in,"%s",ELV.nom)!=EOF)
{

    fscanf(f_in,"%d",&ELV.idelv); // le lis la ligne idelv
    fscanf(f_in,"%d",&ELV.valid); // le lis la ligne valid
    fscanf(f_in,"%s",ELV.nom);   ...
    if (strcmp(ELV.nom,elv)!=0) // fonction de comparaison de deux chaines de caractères --> si elle sont identique faire :  
    {
        ELV.valid=0;
        fprintf(f_in,"%d",&ELV.valid); // je remplace la ligne
    }
    fscanf(f_in,"%s",ELV.prenom);
}
fclose(f_in);
return(EXIT_SUCCESS);

}

mais quand j?exécute ce programme rien ne se passe

Tu as tenté de passer ça au débuggeur ? (genre GDB)

Et au passage, tu ne peux pas remplacer la ligne de cette façon : faut pas oublier qu’un fichier, tant en mode lecture, qu’écriture, à un pointeur indiquant là où se feront les prochaines écritures. Ce pointeur t’est renvoyé par ftell.

En l’occurrence, quand tu fais un fscanf, fprintf, etc, tu fais avancer ce curseur d’une longueur dépendant de ce que tu lis. Et là, dans ton cas, tu fais ça :

je lis le nom
je lis la ligne idelv
je lis la ligne valid
je lis le nom
si strcmp(ELV.nom, elv) == 0 [== identique], j’écris un entier après le nom
je lis le prénom, tu recupères n’importe quoi si ELV.nom == elv.
et ainsi de suite…

Note également, deux chaînes a et b sont identiques si strcmp(a,b) == 0.

je ne métrise pas très bien le débug mais je vais essayer

il faudrait donc que je fasse :
je lis la ligne id
je li la ligne valid
je lis le nom
si le nom correspond je remonte et je change la valeur
si le nom ne correspond pas je lis le prénom et je recommence
?

je rencontre un problème avec la condition while(!EOF), cette boucle devrait s’exécuter tant que la fin de fichier n’est pas atteint non ? car dans mon car le programme ne passe pas dans la boucle

et donc si j’arrive à me placer à la bonne ligne comment remplacer le caractère de cette dernière ?
pour le retour en arrière d’une ligne j’utilise :
fseek(f_in,-1 *sizeof(int), SEEK_CUR); ?

de ce que j’ai pu trouver, la methode a employer serait de copier dans un fichier temporaire en modifiant ce que l’on veut puis d’écraser dans notre fichier source. je vais essayer

Le fseek ne fera pas ce que tu veux, il va juste revenir en arrière de la taille d’un int (4 octets en général). Sauf que tu écris des chaînes, et pas des valeurs binaires : 15445466455645 fait plus de 4 caractères (en tant que chaîne).

Si tu veux faire ta boucle, utilise plutôt ça :

while (!feof(f_in)) {
  ... lire ta structure en une passe ...
}

Si tu veux utiliser fseek, alors n’utilise pas fscanf :

fwrite(elv, sizeof(struct eleve), 1, f_in);
fread(elv, sizeof(struct eleve), 1, f_in);

Mais là, tu ne feras que du binaire, dépendant de ta plateforme.

merci de ton aide j’ai réussi ma boucle avec le feof(f_in) et j’ai utiliser une méthode qui est surement plus lourde à l?exécution mais plus simple à écrire pour moi étant novice: je copie dans un fichier temporaire jusqu’à ce que j’arrive au nom que je veux, je copie avec un 0 à la place du un et je recopie le reste.