Aller au contenu

[RESOLU] langage C et operation sur fichier


Messages recommandés

salut à tous, :francais:

vu le probleme que j'ai avec la gestion des fichier en langage c, j'ai preferer ouvrir un nouveau topic pour faire appel a votre aide.

et je vais essayer de prendre les choses dans l'ordre et d'etre concis.

tout d'abord quand j'execute cette operation :

		rewind(scoring);
	while(j!=EOF)
	{
		j=fgetc(scoring);
		l++;
		printf("%c",j);
	};
	printf("nombre total de caractere dans le fichier = %d\n",l);

j'ai constament le meme probleme, le debug m'affiche :

#~a./out

gros_faignan 4.000000 1
ÿnombre total de caractere dans le fichier = 25
// sauf le caractère "ÿ" qui s'affiche comme un espace dans la console, et n'apparait qu'a la suite d'un copier/coller

sauf que, si je compte le nombre de caractère présent dans le fichier .txt correspondant, j'ai ai 23 pour les caractère + 1 pour le retour de ligne '\n'

donc la seule reponse logique que je trouve a sa serait que '\n' = 2 caractère mais se serait pas très logique.

j'ai egalement fait deux test , avec "while" et "do...while" pour verifier que le caractère en trop ne venait pas du EOF qui aurait pu etre comptabilisé, mais ce n'est pas le cas le resultat est exactement le meme quel que soit la boucle choisie

probleme n°2

ensuite, autre soucis, si par malheur, ma fonction fscanf merdouille un peut lors de l'execution de mon prog. la fin du fichier se trouve augmenter du caractère " ° " ( :pleure: je parle bien de fscanf) et le compilo (visual en l'occurence) me renvoie une infos comme quoi la fin de fichier n'est pas conforme et me propose de la remplacée par "CR LF" pour windows et d'autre truc pour d'autre OS (unix, GNU, etc...)

code d'exemple de ce cas:

	scoring=fopen("scoring.txt","r+");
if(scoring!=NULL)
{
	fseek(scoring,0,SEEK_END);
	if(fprintf(scoring,"%s %f %d\n",joueur.nom,joueur.moyenne,joueur.partie)!=EOF) printf("fprintf=OK\n");
	else printf("fprintf=NOK\n");
	if(fscanf(scoring,"%s %f %d",&x_joueur.nom,&x_joueur.moyenne,&x_joueur.partie)!=EOF)
	{
		printf("fscanf=OK\n");
		printf("%s %f %d\n",x_joueur.nom,x_joueur.moyenne,x_joueur.partie);
	}
	else printf("fscanf=NOK\n");

dans ce cas le debug me sort

#~a./out
fprintf=OK	// le test de mon fprintf
fscanf=OK	// le test de mon fscanf
­º 0.000000 1777608628	 // le printf des valeur de ma struct x_joueur.qqch

gros_faignan 4.000000 1	// ici le printf de ma boucle fgetc présentée au debut du post
ð­ÿnombre total de caractere dans le fichier = 32

jusque la je comprend d'ou vient le probleme, mon fscanf est fait sans que j'ai fait de "rewind()" avant donc mon curseur virtuel et resté positionné par mon "fprintf()" fait juste avant.

ce que je ne comprend pas c'est l'inclusion des " ° " qui sont fait par fscanf (sa peut etre que lui qui le fait parce que quand je le retire sa fonctionne nikel, et en plus c'est ma seule action sur le fichier entre le "fprintf()" et le "fgetc()" qui eux fonctionne). :chinois:

si je pose la question c'est surtout par ce que je trouve ce comportement bizarre.

pour detail je vous mets le contenu de mon ficher après l'execution de cet algo.

#~FILE*./out
gros_faignan 4.000000 1

ð­-º
ð­-

(ici j'ai meme plus que des °, sa dépend des fois).

voila si vous avez des idées elle seront les bienvenues :francais:

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

Pb n°1 :

23 caractères + \n + EOF = 25 :pleure: Tu ne t'arrêtes pas dès que tu trouves le EOF mais après. Tu traites le EOF comme tout les autres caractères. \n représente un seul octet.

Un truc de ce genre ne devrait pas prendre en compte le EOF :

		rewind(scoring);

		j=fgetc(scoring);
	while(j!=EOF)
	{
		l++;
		printf("%c",j);
		j=fgetc(scoring);
	};
	printf("nombre total de caractere dans le fichier = %d\n",l);

Cordialement,

Barroud.

Lien vers le commentaire
Partager sur d’autres sites

problème numéro 2: printf/scanf sont de bonnes libs. mais ça ne les empêche pas d'avoir un comportement indésirable sous certaines conditions.

(enfin, j'imagine que c'est le cas ici, et j'ai pas vraiment envie de lister les différentes causes vaudou qui pourraient être à l'origine de ton problème)

le plus probable : ton fichier est encodé dans un jeux de caractères qui n'est pas celui utilisé par défaut par ton système.

quoi qu'il en soit, write() et read() sont plus indiqués dans ces situations.

tu peux ainsi adapter le comportement de ton programme en fonction de ce que tu vas croiser.

d'autant plus qu'elles sont à la base de n'importe quel échange de flux.

scanf/printf, c'est sympa pour debug/jouer/alléger ton code/...

mais, étant débutant, tu devrais jeter un oeil sur les vrais appels systèmes, plutôt que sur des usines à gaz dont tu ne comprends pas le fonctionnement en détails (c'est normal quand on apprend) ^^

après, libre à toi de recoder printf : ce sera l'occasion de voire les varargs, plancher sur les petits tricks d'algo simples mais utiles (transformation de caractères en nombres, et inversement, ...), création de librairies, ... travail sur la compatibilité entre les différents systèmes/architectures, ...

Lien vers le commentaire
Partager sur d’autres sites

bon j'ai fini par trouver une solution a mon pb de fscanf, sans trouver pourquoi elle produit le resultat dont je parler plus haut, j'ai trouver le moyen de faire une fonction qui ecrit une chaine formater dans un fichier, puis qui les lit les une a la suite des autre grace a fscanf puis renvoie le nombre de ligne lue.

enfin, histoire de pas etre limité a fscanf et fprintf, j'ai voulu tester fread et fwrite et sur ce point j'ai quelque petit soucis

	scanf_s("%s",test,TAILLE);
score=fopen("test.txt","r+");
if(score!=NULL)
{
	fwrite(test,sizeof(test),strlen(test),score);
	rewind(score);
	fread(test2,sizeof(test),strlen(test),score);
}
else exit(0);
printf("%s",test2);
fclose(score);

mon probleme jusque la c'est que bien que mes fonction fread et fwirte fonctionne (a priori - puisque le dernier printf me renvoie bien la valeur entré dans test puis transferer a test2, visual me renvoie un "Debug assertion failed" pour (stream!=NULL) et crée un point d'arret sur flcose (sois disant ligne 47 dans la dll ché-pas-koi)

donc la si quelqu'un pouvait eclairer ma lanterne j'avoue que sa serait sympa

a noter a ce propos que pour fread et fwrite j'ai egalement tester le code comme ceci

	if(score!=NULL)
{
	fwrite(test,strlen(test),sizeof(test),score);
	rewind(score);
	fread(test2,strlen(test),sizeof(test),score);
}

en contradiction avec ce qu'explique cplusplus.com sur fread et fwrite, et curieusement se code fonctione egalement et me renvoie la meme erreur

noter que sur le site de cplusplus, sauf erreur, leurs explication sont egalement en contradiction avec l'exemple qu'ils donnent.

pour info voici la sortie de mon file (et encore ya pas tout)

FILE* /out
깸வ줨஡Ԝ깸வ줨஡Ԝ깸வ줨஡Ԝ깸வ줨஡Ԝ

:byebye:

bon bas si quelqu'un sais lire ce langage sa m'interesse aussi :sm:

Lien vers le commentaire
Partager sur d’autres sites

Comment as-tu déclaré ta variable test ?

En attendant petite remarque : si score est nul, tu ouvre le fichier mais tu ne le fermes jamais. Ceci est mal ! Il faut toujours fermer correctement ses ressources ! :pastaper:

comme un tableau de char, pareil pour test2,

bas justement si score est nul c'est que mon fichier ne c'est pas ouvert donc je peut pas le fermer, remarque a ce moment la , theoriquement mon fclose devrait se retrouver avant le exit(0).

PS => au passage y a t'il un strlen pour les nombre de type float et int

Lien vers le commentaire
Partager sur d’autres sites

Ah oué score c'est le fichier , chui un peu fatigué moi :cartonrouge:

L'erreur vient sûrement du fait que sizeof(tableau) renvoie le nombre d'éléments dans un tableau et non la taille d'un élément du tableau. Donc au final, si ta variable test contient "blablabla", tu demandes à fwrite d'écrire 9 éléments (strlen) de 10 octets (sizeof) dans score (et non 9 éléments d'un octet comme il se devrait).

Pour le strlen de nombres.. ça n'a pas vraiment de sens... Au pire tu transforme le nombre en chaîne et ensuite tu mesures sa taille...

Lien vers le commentaire
Partager sur d’autres sites

Est-ce que tu pars d'un fichier vide ? C'est peut-être des caractères chinois déjà présents ?

oui, j'ai vider mon fichier plusieur fois, en retestant l'operation mais c'est toujours pareil.

j'ai peut etre trouver une reponse, mais peut etre seulement, apparament fwrite et fread ne serait fait que pour ecrire en binaire. maintenant sa reste a confirmer.

[EDIT]

bas sa a l'air d'etre le cas, j'ai trouver un truc qui le confirme a moitié : a moitié seulement puisqu'il sagit d'un cours sur MatLab donc forcement l'etrapolation reste sujette a caution.

http://iramis.cea.fr/spec/GIT/FTP/3_Fichie..._de_donnees.pdf page 2 paragraphe 2 : lecture de fichier binaire.

sinon a part sa j'ai besoins d'un autre petit coup de pied :cartonrouge: sur autre chose :

		while(feof(scores)==0)
	{
		fscanf(scores,"%s %f %d",xjoueur.xnom,&xjoueur.xmoyenne,&xjoueur.xpartie);
		printf("%s %f %d\n",xjoueur.xnom,xjoueur.xmoyenne,xjoueur.xpartie);
	}

le soucis c'est que sa me printf toujours la dernière ligne 2 fois

j'ai reussi a resoudre le probleme en faisant comme sa

		while(feof(scores)==0)
	{
		if(fscanf(scores,"%s %f %d",xjoueur.xnom,&xjoueur.xmoyenne,&xjoueur.xpartie)!=EOF)
		printf("%s %f %d\n",xjoueur.xnom,xjoueur.xmoyenne,xjoueur.xpartie);
		else;
	}

mais je trouve pas sa vraiement tip top dans le sens ou quelque part sa revient a tester la meme condition 2 fois.

alors l'autre solution qui fonctionne aussi c'est de test la valeur de fscanf directement dans le while.

mais comme je suis un peut casse coui**e ce qui m'arrangerais serait d'utiliser feof puisque apparament sa deplace pas mon curseur virtuel ce qui m'arrange pour la suite de l'algo.

en gros pour dire ce que je cherche c'est un moyen d'eviter se probleme dans mon while, sans utiliser une instruction qui déplace mon curseur. (ou sinon un miracle me convient aussi)...

Lien vers le commentaire
Partager sur d’autres sites

certes, fread et fwrite sont particulièrement utiles pour travailler avec du binaire.

mais c'est un read/write. dans le principe, ça lit/écrit n'importe quoi.

1) ce n'était très probablement pas du chinois (ça m'étonnerais que tu ais les locales adéquates): ce qui m'étonnerait moins, c'est que tu ais lu certains trucs de travers

2) si vraiment ça te casse les couilles de mettre le fscanf comme condition de boucle, le plus simple serait sans doute:

while (feof(scores) == 0 && fscanf([...]))
fprintf([...]);

la première condition ne passant pas, la suivante ne sera pas testé.

3) faire un if pour une instruction conditionnelle, OK. faire un else pour mettre un ;, je vois pas bien l'intérêt ^^

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...