Lecture d'un fichier binaire

Résolu/Fermé
omarr - 14 janv. 2011 à 21:47
 omarr - 16 janv. 2011 à 16:18
Bonjour,


je voudrais stocker un texte (en fait ,c'est juste un ptit texte) dans une liste chainée en langage C ;chaque chaine va contenir 3 caractères; mais ça pose encore un prob ; voici ce que j'ai arrivé à faire :

while(!foef(mon_fichier_bin))
{
fread(buffer,1,sizeof(char)*3,mon_fichier_bin)
liste_chainee=ajouter(liste_chainee,buffer);

}

mais lorsque je vous afficher les champs de la liste chainée , il y a seulement la première chaine qui est stockée !!

je serai reconnaissant de vos aides; je suis un débutant en la manipulation des fichiers !!!!

et merci d'avance




A voir également:

4 réponses

Bonjour

voici le code complet de mon programme :


/* fread example: read a complete file */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// structure d'une chaine :
typedef struct _ac{
char *nom;
int ordre;
struct _ac* suivant;
}ac;
int i=0;


typedef ac* acide;
int taille=sizeof(ac);
acide ajouter(acide liste_acide,char* acide_amine);

int main () {
FILE * pFile=NULL;
char * buffer;
acide list_acide_true=malloc(taille);

// ouverture du fichier binaire en mode lecture
pFile = fopen ( "myfile.bin" , "r+b" );
if (pFile==NULL) {fputs ("File error\n",stderr); exit (1);}

// allocation de la mémoire au buffer
buffer = (char*) malloc (sizeof(char)*3);
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}

// lecture du fichier binaire tant qu'on a pas arrivé à la fin du fichier
while(!feof(pFile)){
result = fread (buffer,1,sizeof(char)*3,pFile);
if(!strcmp(buffer,"ATG"))
{list_acide_true=ajouter(list_acide_true,"Met"); i+=3;}
else if(!strcmp(buffer,"TGG"))
{list_acide_true=ajouter(list_acide_true,"Trp"); i+=3;}
}
// terminate


ac* tmp=list_acide_true;
while(tmp!=NULL)
{ printf(" \n\t%d %s \n",tmp->ordre,tmp->nom);
tmp=tmp->suivant;
}


fclose (pFile);
free (buffer);
return 0;
}

// la fonction qui ajoute les 3 caractères à la fin de la liste chainée
acide ajouter(acide list_acide,char* acide_amine)
{
ac* new_acide=malloc(taille);
//if(new_acide==NULL) {fputs("erreur de memoire",stderr); exit(1);}
new_acide->nom=malloc( strlen(acide_amine)+1 );
strcpy(new_acide->nom,acide_amine);
new_acide->ordre=i/3;
new_acide->suivant=NULL;
if(list_acide==NULL)
return new_acide;
else{
ac* tmp=list_acide;

while(tmp->suivant!=NULL)
{
tmp=tmp->suivant;
}
tmp->suivant=new_acide;
return list_acide;
}
}



le texte que j'envoie à l'exécutable contient les deux cas que j'ai cité càd :
ATG TGG ; avec exactement un espace entre les deux mots ;
je voudrais lire 3 caractères par 3; et les stocker dans ma liste chainée
mais lorsque je veux afficher le contenu de la liste chainée je me trouve seulement avec ça :
0 (null)

0 Met

pouvez-vous m'expliquer ça ??
et merci d'avance
1
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
14 janv. 2011 à 22:08
On ne pourra pas t'aider totalement sans connaître la totalité du code concerné.
En particulier on ne sait pas comment tu as construit liste_chainee, ni comment tu as codé ajouter. Et puis quel est ton problème ? (Qu'as-tu ? Que veux-tu ?)

Avec les seules informations que tu nous donnes je ne vois qu'une erreur :
Ce n'est pas foef qui s'applique à un fichier mais feof.
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
15 janv. 2011 à 16:09
Remarque : tu peux définir ton type acide en même temps que ac.
typedef struct _ac
{ 
	char *nom; 
	int ordre; 
	struct _ac* suivant; 
}	
ac, *acide;
Et maintenant que le type acide est défini, on ne devrait plus voir de ac* or tu en utilises encore (ce n'est pas faux en soit, mais autant être cohérent)

Il te faut faire des cast devant les malloc, déclarer la variable result.
De plus, évite de déclarer et initialiser des variables globales telles que int i=0;, tu peux par exemple la déclarer localement dans le main, et la passer comme paramètre à ta fonction ajouter. De plus tu fais toujours i+=3 comme incrémentation mais tu l'utilises avec i/3, autant faire i++ dans ce cas !

Autre remarque, tu n'es pas obligé d'allouer dynamiquement la mémoire de buffer puisque tu connais sa taille à l'avance. Tu pourrais faire char buffer[3];.
Mais en fait ça va te poser un problème :

Quand tu fais strcmp(buffer,) aucune des deux valeurs à comparer "ATG" et "TTG" n'est acceptée à cause de l'absence du \0 à la fin de buffer. Il faut donc rajouter une instruction buffer[3]='\0', ce qui nécessite de déclarer char buffer[4];.

Autre problème, dans ta liste cette fois, tu alloues liste_acide_true en mémoire mais sans l'initialiser, en particulier sans définir son suivant à NULL.
Il serait plus judicieux d'initialiser liste_acide_true à NULL, pour permettre la fonction ajouter d'utiliser le cas if (list_acide==NULL)

Maintenant que le premier tour de boucle fonctionne on passe à TTG, mais le problème c'est que l'espace est considéré comme le premier caractère de la nouvelle chaîne et on a " TG". Ce qu'il faut c'est soit enlever les espaces dans le texte, soit toujours lire 4 caractères et remplacer l'espace par le '\0' (ce que je vais faire) :
result = fread (buffer,1,4,pFile); // "ATG ", "TTG "...
buffer[3]='\0';


Maintenant, lorsque result==0 ça signifie que l'on ne lit plus rien, il faut donc s'arrêter. On pourrait même être plus strict en disant result<3 ce qui signifie que la ligne est incomplète, mais dans ce cas on est sûr que les strcmp échoueront donc ça revient au même. Il ne reste plus qu'à fermer le fichier ce que l'on peux faire avant l'affichage des printf.

Dernière chose, et pas des moindre, que je te laisse faire tout seul : une fois le programme terminé il faut libérer la mémoire de chaque maillon de la liste !

/* fread example: read a complete file */ 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

// structure d'une chaine
typedef struct _ac
{ 
	char *nom; 
	int ordre; 
	struct _ac* suivant; 
}	
*acide; 

// la fonction qui ajoute les 3 caractères à la fin de la liste chainée 
acide ajouter(acide list_acide, char* acide_amine, int i) 
{ 
	acide new_acide = (acide) malloc(sizeof(struct _ac)); 
	{
		new_acide->nom = (char*) malloc( strlen(acide_amine)+1 );
			strcpy(new_acide->nom, acide_amine);	
		new_acide->ordre=i; 
		new_acide->suivant=NULL; 
	}

	if (list_acide==NULL) 
		return new_acide; 
	else
	{ 
		acide tmp = list_acide; 

		while(tmp->suivant!=NULL) 
		{ 
			tmp=tmp->suivant; 
		}

		tmp->suivant=new_acide; 

		return list_acide; 
	} 
}

int main ()
{
	// ouverture du fichier binaire en mode lecture 

	FILE * pFile = fopen("D:\\myfile.bin","r+b"); 

	if (pFile==NULL) 
	{
		fputs ("File error\n",stderr);
		exit (1);
	} 

	// lecture du fichier binaire tant qu'on a pas arrivé à la fin du fichier 

	acide list_acide_true=NULL; 
	char buffer[4];
	int i; // ordre des acides

	// on lit 3 lettres et 1 espace (facultatif en fin de fichier)
	for (i=0; fread(buffer,1,4,pFile)>=3; i++)
	{ 
		buffer[3]='\0'; // remplace l'espace lu par par une fin de mot
		
		if(!strcmp(buffer,"ATG")) 
			list_acide_true=ajouter(list_acide_true,"Met",i);
		else if(!strcmp(buffer,"TGG")) 
			list_acide_true=ajouter(list_acide_true,"Trp",i);
	}

	fclose (pFile);

	// lecture dans l'ordre de la liste

	acide tmp;
	for (tmp=list_acide_true; tmp!=NULL; tmp=tmp->suivant) 
	{
		printf("%d %s\n",tmp->ordre,tmp->nom); 
	} 

	// désallocation mémoire de la liste

	// ...

	return 0; 
}
0
Bonjour

Mes remerciements ; j'apprécie bcp vos conseils

@ la prochaine fois inchalah
0