Modifier un fichier en C

£udo Messages postés 455 Date d'inscription   Statut Membre Dernière intervention   -  
 SKZ81 -
salut , j' ai un souci avec un fichier en C. Mon pg permet les gestion des absences, des retard et des retenues par trimestre. Voila j'ai la structure suivante :
struct eleve
{
  int identifiant;
  char nom[LG];
  char prenom[LG];
  char classe[LG];
  char numtel[LG];
  int retard;
  int absence;
  int retenue;
  int retard_trim1;
  int absence_trim1;
  int retenue_trim1;
}seleve ;


je voudrais grace a une fonction reinitialiser les champs retard, absences et retenues pour les mettre dans les champs retard_trim1, absences_trim1 et retenues_trim1, pour ensuite les remettre a 0. J'ai essayé comme ça :
void reinit_eleve()
{
       		
	char rep;
	int compteur;
	printf("Vous allez reinitialiser \n\nles -retenues\nles -absences\nles -retards\n\ndu trimestre en cours\n");
	printf("Voulez vous continuez ?\n");
	scanf("%c",&rep);
	flushall();


	fichier_eleve=fopen("fichier1_eleve","wb");//on ouvre le fichier
	if((rep=='o')|| (rep=='O'))
	{
		while (fread (&seleve, sizeof(seleve),1,fichier_eleve) != 0)//tant qu'on lit dans le fichier
		{
		fseek(fichier_eleve,sizeof(seleve)*(seleve.absence),SEEK_SET);	
		seleve.absence_trim1=seleve.absence;
		compteur=compteur+1;
		}
    }//fin if            
	else
	{
		printf("Il n'y a pas d'eleve dans la base...\n\n");
	}

	fseek(fichier_eleve,sizeof(seleve)*(seleve.absence),SEEK_SET); //SEEK SET faire bouger le curseur du pointeur
	//on se replace a l'endroit du fichier où se trouve l' eleve
	fwrite(&seleve,sizeof(seleve),1,fichier_eleve);
	//on écrit le client dans le fichier, par dessus
	fclose(fichier_eleve);//fermeture du fichier
getch();


}


Le bleme c'est ke ça passe pas et je sais ke y a des soucis mais je vois pas ou.

Qqn peut m'aider plizz?

(¯`·.¸¸.-> £udo <-.¸¸.·´¯)
A voir également:

7 réponses

blurk Messages postés 486 Date d'inscription   Statut Membre Dernière intervention   160
 
salut!

y'a pas de solution miracle:
il n'y a pas d'insertion,
il n'y a que de l'ajout en fin de fichier.
(enfin avec les librairies de base du C ansi, et à ma connaissance)
mais je connais 2 manières de faire:
A/
1 lire le fichier,
2 tout mettre en mémoire
3 modifier
4 réécrire en écrasant le fichier

B/
1 lire le fichier source en lecture
2 creer un fichier cible avec un nouveau nom
3 faire une boucle qui lit le fichier source
et ecrit dans la cible la fiche avec eventuellement
les modifications (qui n'ecrit pas si la fiche est supprimée)
4 fermer les fichiers
5 effacer le fichier source
6 renomer le fichier cible avec le nom du fichier source

la solution A est rapide à l'exécution, mais il faut pas
se planter avec l'allocation mémoire.

la solution B est lente à l'exécution
(en effet un disque dur est plus lent que la mémoire vive)
mais le traitement est plus fiable, moins de risque
de perte des données.

Je sais pas si ça peut te servir, mais les autre méthodes
si il y en a, doivent être hyper complexes et de toutes façon
pas aussi rapide.

cordialement
3
SKZ81
 
Plusieurs choses :
>> fichier_eleve=fopen("fichier1_eleve","wb");
"wb", hum... Le b pour binaire, c'est bien, mais le w écrase le contenu du fichier. Essaye "wb+" ou encore "ab", ça devrais déjà éviter d'effacer ton fichier à chaque fois, si c'est pas ça que tu veux faire. Passons pour le moment.

>> fseek(fichier_eleve,sizeof(seleve)*(seleve.absence),SEEK_SET);
Hou !! L'horreur !!
Avec le "*(seleve.absence)", tu te déplace dans le fichier (depuis le début, à cause de SEEK_SET, ton explication en commentaire est flou, on pense plutôt à SEEK_CUR) Tu te déplace donc dans le fichier vers l'élève N°abscence de l'élève considéré. Bref, du charabia. Je comprend même pas ce que tu voulais faire.

Bref, pour moi il serait bien de fixer d'abors les choses.
L'idée est de :
- Ouvrir le fichier
Tantque(il reste des élèves) {
- Lire un élève.
- Modifier ses attributs (n'oublie pas au passage de réinitialiser à zéro !!!)
- Revenir en arrière dans le fichier avec fseek. La solution la plus propre est de faire un déplacement -1*sizeof(seleves), afin de se recaler juste sur la structure (en utilisant SEEK_CUR)
(Eventuellement, faire un déplacement de N°élève*sizeof(seleves) MAIS IL FAUT ETRE SÛR QUE LES ELEVES SONT DANS L'ORDRE ET QU'IL N'Y A PAS DE TROU, hypothèse non réaliste (sinon ton N° d'étudiant changerais au moins tout les ans)).
- Ecrire cet élève, donc AU MEME emplacement.
}
- Fermer le fichier

Voilà, je te laisse adapter ça en C... (Pas faire tout le bouleau non plus :P )
1
£udo Messages postés 455 Date d'inscription   Statut Membre Dernière intervention   16
 
Merci pour votre aide mais tout ne se passe pas comme je le veux.
voila la partie du code que j'ai modifier
	
	fichier_eleve=fopen("fichier1_eleve","r+");//on ouvre le fichier
	if((rep=='o')|| (rep=='O'))
	{
		while (fread (&seleve, sizeof(seleve),1,fichier_eleve) != 0)//tant qu'on lit dans le fichier
		{
		
		//fseek(fichier_eleve,sizeof(seleve),SEEK_SET);
               seleve.retard=0;
                seleve.absence=0;
                seleve.retenue=0;
		//seleve.absence_trim1=seleve.absence;
		
		}
             fseek(fichier_eleve,sizeof(seleve),SEEK_SET); //SEEK SET faire bouger le curseur du pointeur
	        //on se replace a l'endroit du fichier où se trouve l' eleve
	        //fwrite(&seleve,sizeof(seleve),1,fichier_eleve);
	        //on écrit le client dans le fichier, par dessus
	        fclose(fichier_eleve);//fermeture du fichier
        }           


alors quand je l'execute il ne se passe rien. Il retourne au menu sans rien modifier. J'ai testé avec 2 eleves dans le fichier.
Le probleme doit venir du fseek, je ne sais pas comment bien l'utiliser et quelles elements mettre a l'interieur.

J'aimerai des explications car j'ai pas pigé cela :
Revenir en arrière dans le fichier avec fseek. La solution la plus propre est de faire un déplacement -1*sizeof(seleves), afin de se recaler juste sur la structure (en utilisant SEEK_CUR)
(Eventuellement, faire un déplacement de N°élève*sizeof(seleves) MAIS IL FAUT ETRE SÛR QUE LES ELEVES SONT DANS L'ORDRE ET QU'IL N'Y A PAS DE TROU, hypothèse non réaliste (sinon ton N° d'étudiant changerais au moins tout les ans)).

Quand tu dis qu'il ny a pas de trous, cela veut dire que tout les eleves sont enregistrés les uns a la suite; Si c'est le cas, oui.

Comment resoudre mon probleme ??

Merci
(¯`·.¸¸.-> £udo <-.¸¸.·´¯)
0
Ravachol Messages postés 566 Date d'inscription   Statut Membre Dernière intervention   120
 
Salut,
Comme ceci peut-être ?
  fichier_eleve=fopen("fichier1_eleve","r+b");//on ouvre le fichier
  if((rep=='o')|| (rep=='O'))
  {
    while (fread (&seleve, sizeof(seleve),1,fichier_eleve) != 0)//tant qu'on lit dans le fichier
    {
      seleve.retard_trim1=seleve.retard;
      seleve.retard=0;
      seleve.absence_trim1=seleve.absence;
      seleve.absence=0;
      seleve.retenue_trim1=seleve.retenue;
      seleve.retenue=0;
      fseek(fichier_eleve, sizeof(seleve) * -1,SEEK_CUR);	
      fwrite(&seleve,sizeof(seleve),1,fichier_eleve);
    }
  }//fin if            
  else


A++
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
£udo Messages postés 455 Date d'inscription   Statut Membre Dernière intervention   16
 
j' ai essyé avec ta propostion avec 3 eleves dans le fichier, les champs revienent a 0 mais ensuite quand je le consulte, je me retrouve avec 3000 eleves. Et aussi apres avoir mis oui au choix, il ne reviens pas au menu.
Et que veux dire l'etoile a cette ligne la
fseek(fichier_eleve, sizeof(seleve) * -1,SEEK_CUR);


merci de ton aide
(¯`·.¸¸.-> £udo <-.¸¸.·´¯)
0
Ravachol Messages postés 566 Date d'inscription   Statut Membre Dernière intervention   120
 
Re,
Je viens de tester avec un fichier de 5 élèves et je n'ai pas de pb chez moi, mais bon comme je n'ai pas ton prog en entier...
Le code que je te proposais n'est que la partie du if qui est exécutée si la réponse au choix est "oui". C'est pour cela que j'ai laissé le else.

L'étoile c'est l'opérateur de multiplication, * -1 sert à obtenir un deplacement négatif, vers le début du fichier, relativement à la position courante de l'indicateur. En l'occurence on se replace au début de la structure de l'élève concerné.

A++
0
DestyNov@
 
Ben moi j'aurais qu'une chose à dire, il ne faut pas aider qq'un qui fait une appli pour gérer les absences et retard des élèves.
Tu sais comment on appelle ça SKZ81 ? la collaboration !!!

;-)
-1
SKZ81
 
DestyNov@ >> Hey, l'autre, hé !!!

Oui, oui, je collabore...
Avec mes amis developpeurs !!!


PS : Laisse tomber, je suis blasé, j'ai bossé (de loin, mais quand même...) pour les forces balistiques nucléaires françaises... Moi on m'avais "ben... y'a des radars sur un bateau..." Evidement, j'ai OUBLIE de demander à quoi servait les radars, et c'était pas à scruter les poissons, mais plutôt des missiles...

Alors les retards et abscence, tu comprendra, je m'en tape un peu... ;°)
-1