Aller au contenu

[RESOLU] arrachage de cheveux sur les pointeurs


Messages recommandés

Spaz001 à raison sur le strdup()

(par contre, le malloc se fait de sizeof(char*)*(strlen(ptr)+1), pour compter le '\0')

écrire char *ptr = "" attribue à ptr une chaine statique, donc, que tu ne pourra pas free()

l'intérêt du strdup est dans le malloc.

sinon, on aurait pu se contenter d'un ptr= malloc(1); et d'un memset(ptr, 0, 1); (ou, à défaut du memset, un ptr[0]=0; )

dans le strdup, comme pour allouer de la mémoire à n'importe quelle chaîne (ou autre), tu malloc l'élément nécessaires (le sizeof) multiplié par le nombre d'éléments (la len + 1). Ca revient à créer un char toto[len + 1];, sauf qu'il s'agit d'un pointeur, et non d'une variable statique.

rappelons que la taille d'un pointeur n'est pas statique (puisqu'il s'agit d'un pointeur...), d'où la différence avec la variable statique.

par ailleurs, essaye de prototyper une fonction retournant `myobject_t toto[42][21]'. tu vera l'intérêt d'utiliser des pointeurs :cartonrouge: (ou à défaut, tu apprendra à caster comme un gauret)

En mémoire, les emplacements sont alloués consécutivement (ce qui te permet de te déplacer en utilisant &ptr[inc], pointant sur le début de ta chaine + inc éléments), qu'il s'agisse de statiques ou de pointeurs

par contre, suivant s'il s'agit de variables statiques ou de pointeurs, ça n'ira pas se mettre au même endroit, en mémoire (enfin, c'est du moins le cas sous linux)

Lien vers le commentaire
Partager sur d’autres sites

  • Réponses 104
  • Créé
  • Dernière réponse

Ahh, j'ai oublié le +1 '^^

Il y a une autre raison au strdup.

Ton ptr est déclaré en tant que char *

Tu insinues donc que ptr pointe vers une chaine de caractère dont tu peux modifier les caractères.

Or, les chaînes littérales sont dans un espace mémoire qui est censé être en lecture seul.

char * ptr = "ttt";

ptr[1] = 'b';

est censé te lancer une violation d'accès.

C'est pour ça que tu dois strdup, pour que ta chaîne soit dans un espace modifiable.

Mais tu dois penser à la libérer après utilisation.

Lien vers le commentaire
Partager sur d’autres sites

Spaz001 à raison sur le strdup()

(par contre, le malloc se fait de sizeof(char*)*(strlen(ptr)+1), pour compter le '\0')

écrire char *ptr = "" attribue à ptr une chaine statique, donc, que tu ne pourra pas free()

l'intérêt du strdup est dans le malloc.

sinon, on aurait pu se contenter d'un ptr= malloc(1); et d'un memset(ptr, 0, 1); (ou, à défaut du memset, un ptr[0]=0; )

donc si j'ai bien compris memset remplace_en_memoire, dans ce cas : le premier octet (3e arg) par 0 (2e arg) dans la variable dont l'adresse est contenue par ptr (1er arg).

dans le strdup, comme pour allouer de la mémoire à n'importe quelle chaîne (ou autre), tu malloc l'élément nécessaires (le sizeof) multiplié par le nombre d'éléments (la len + 1). Ca revient à créer un char toto[len + 1];, sauf qu'il s'agit d'un pointeur, et non d'une variable statique.

en gros c'est une facon "detournée" de creer un tableau[variable]

my_object t c'est une structure ...?

alors sinon histoire de bosser un peut j'ai tenter de faire des traduction de cplusplus .com, je me suis dit que se serait un bon exercice, meme si je promet pas de le faire pour toutes le libs.

si vous avez le temps d'y jeter un oeil, surtout hesitez pas a me corrgier si je laisse trainer des erreur (j'ai laisser des truc en rouge quand sa me semblait plutot pas tip top), meme si quelque part ce sera pas forcement très utile vue que la plupart des programmeur parle courament anglais.

malloc : http://docs.google.com/View?id=dgvvj8gj_13hps4jddt

memset : http://docs.google.com/View?id=dgvvj8gj_1447dxqcd7

setbuf : http://docs.google.com/View?id=dgvvj8gj_15cj4s9nf2

pour setbuf je vous mets le lien sur cplusplus.com par ce qu'il y a pas mal d'erreur ...

http://www.cplusplus.com/reference/clibrary/cstdio/setbuf/ :zarb:

PS : @Spaz001 : effectivement je crois que sa m'a deja fait le coup et que j'avais pas compris pourquoi, d'ailleur toujours pas puisque quelque part si ya un

const char *toto

c'est justement pour verrouiller la modification de chaine. :zarb:

=>

PS2: @tous ceux qui ont ecrit le langage C : pourquoi faire simple quand ont peut faire compliqué ??? :roll:

Lien vers le commentaire
Partager sur d’autres sites

Spaz001 à raison sur le strdup()

(par contre, le malloc se fait de sizeof(char*)*(strlen(ptr)+1), pour compter le '\0')

écrire char *ptr = "" attribue à ptr une chaine statique, donc, que tu ne pourra pas free()

l'intérêt du strdup est dans le malloc.

sinon, on aurait pu se contenter d'un ptr= malloc(1); et d'un memset(ptr, 0, 1); (ou, à défaut du memset, un ptr[0]=0; )

donc si j'ai bien compris memset remplace_en_memoire, dans ce cas : le premier octet (3e arg) par 0 (2e arg) dans la variable dont l'adresse est contenue par ptr (1er arg).

memset set en mémoire, pour son premier argument (void*), la valeur de son deuxième argument, sur la len indiqué par le troisième.

dans le strdup, comme pour allouer de la mémoire à n'importe quelle chaîne (ou autre), tu malloc l'élément nécessaires (le sizeof) multiplié par le nombre d'éléments (la len + 1). Ca revient à créer un char toto[len + 1];, sauf qu'il s'agit d'un pointeur, et non d'une variable statique.
en gros c'est une facon "detournée" de creer un tableau[variable]

my_object t c'est une structure ...?

c'est ce que tu veux.

mais puisque tu demandes ça, c'est probablement que tu ne l'a pas encore vu.

typedef te permet de créer un type que tu aura défini.

exemples:

typedef size_t unsigned int;
typedef struct s_toto t_toto;
typedef struct myobject_s
{
int				 id;
char				*name;
time_t			  date;
struct myobject_s   *next;
struct myobject_s   *prev;
t_toto			  *toto;
} myobject_t;

après, j'imagine que tu as déjà vu (au moins croisé) l'utilisation des structures:

struct s_toto pouet;
pouet.id = 5
pouet.name = strdup("toto");
etc.

ce que tu n'as sans doute pas vu, c'est l'utilisation de pointeurs sur structures.

là, comme pour tout pointeur, on commence par malloc();

myobject_t *toto;

toto = malloc(sizeof(myobject_t));
toto->id = 5;
toto->name = strdup("toto")
toto->next = NULL;

et (on passe un peu vite, ça va te faire tripper), les listes chainées, qui sont des 'tableaux' de structures, ou plutôt, un pointeur sur une suite de structures. comme ça:

myobject_t *toto = NULL, *tmp;
int x;

while (x++ < 10)
{
tmp = malloc(sizeof(myobject_t));
tmp->id = x;
asprintf(&tmp->name, "name%d", x);
tmp->prev = toto;
if (toto) toto->next = tmp;
toto = tmp;
}
tmp->next = NULL;
/* et pour revenir au début de ta liste
while (tmp->prev)
tmp = tmp->prev;
*/

jte laisse comprendre, mais c'est pas sorcier.

ici, on a créé une liste doublement chaîné (si jme suis pas planté dans l'algo ^^)

le principe:

une liste chaîné est composées de structures, où chacune d'entre elles comporte un pointeur vers l'élément suivant de la liste.

la liste doublement-chaînée: même principe, mais on a également un élément dans chaque maillon permettant de remonter à l'élément précédant.

liste circulaire: peut être chaîné ou doublement-chaînée, du moment que le dernier élément renvoit sur le premier (et le premier sur le dernier, si doublement chaînée)

alors sinon histoire de bosser un peut j'ai tenter de faire des traduction de cplusplus .com, je me suis dit que se serait un bon exercice, meme si je promet pas de le faire pour toutes le libs.

si vous avez le temps d'y jeter un oeil, surtout hesitez pas a me corrgier si je laisse trainer des erreur (j'ai laisser des truc en rouge quand sa me semblait plutot pas tip top), meme si quelque part ce sera pas forcement très utile vue que la plupart des programmeur parle courament anglais.

j'y jetterai un oeil. mais tu aurais plus vite fait "d'apprendre l'anglais" (ce qui est nécessaire à la prog, c'est très réducteur par rapport à l'anglais)
Lien vers le commentaire
Partager sur d’autres sites

Juste histoire de j'ai donc essayer de terminer mon code d'ecriture dans mon FILE* et en gros sa donne sa (bon c'est pas encore tout a fait au point)

typedef struct save_score save_score;
struct save_score
{
char nom[TAILLE];
float moyenne;
int partie;
};

/******************************
* ...................code.......................*
******************************/
scoring=fopen("scoring.txt","r+");
if(scoring!=NULL)
{
	rewind(scoring);//pour etre sur d'etre au debut de mon file
	while(fscanf(scoring,"%s %d %d",x_joueur.nom,&x_joueur.moyenne,&x_joueur.partie)!=EOF)//je boucle et lisant chacune des donnés formatées tant que je suis pas à la fin de file(c'est a dire pas du tout s'il est vide)
	{
		if(strcmp(x_joueur.nom,joueur.nom)==0)
		{
			fseek(scoring,-(strlen(x_joueur.nom)+sizeof(x_joueur.moyenne)+sizeof(x_joueur.partie)+1),SEEK_CUR);//vue que je vient de lire la valeur je doit repositionner mon "curseur" au debut de la ligne en soustrayant la "taille lue" (probleme de calcul evident)
			x_joueur.moyenne=(x_joueur.moyenne+joueur.moyenne)/2;
			x_joueur.partie+=joueur.partie;
			fprintf(scoring,"%s %d %d\n",x_joueur.nom,x_joueur.moyenne,x_joueur.partie);
		}
		else
		{
			fseek(scoring,0,SEEK_END);
			fprintf(scoring,"%s %d %d\n",x_joueur.nom,x_joueur.moyenne,x_joueur.partie);
		}
	}
	fseek(scoring,0,SEEK_SET);
	if(fgetc(scoring)==EOF)
	{
		rewind(scoring);
		fprintf(scoring,"%s %d %d\n",x_joueur.nom,x_joueur.moyenne,x_joueur.partie);
	}
}
else printf("fichier impossible d'acces");
fclose(scoring);
}

ouaip bah c'est pas au point, :fumer:

je pense que je trouverais ma solution dans ce les pointeur de struct par ce qu'entre les problemes d'adresses, de valeur de tableau et de pointeur un peut partout c'est vite galère.

(mais le plus bizarre c'est que sa ecrit en chinois dans mon fichier ??? a mon qu'il implemente l'unicode qui sauf erreur de ma part est le seul a integrer le chinois, je sais pas trop d'ou sa sort :zarb: )

sinon le calcul du nombre d'octet réellement utilisé dans mes struct variable serait plus simple si je remplacait mon tableau (dans ma struct) par un pointeur puis que je lui collais un malloc correspondant a ma string, mais bon ce sera pour demain...

par contre je pense que j'ai pas besoins de setbuf par ce qu'en fait, si je positionne mon curseur au bonne endroit sa ecrase les données du fichier qui etait la avant ....(j'en connait un qui va me dire que je suis un vrai goret)

en tout cas c'est apparament le cas avec fwrite, a verifier pour fprintf...

pour ce qui conerne l'anglais, bah ouep :craint: , je l'avoue mon niveau est encore très scolaire.

mais je risque pas d'apprendre a parler avec des tuto ou ni meme sur des forum, pour sa y faut du terrain.

A un moment j'avais cherché un job en angleterre du genre "serveur, balayeur, ou meme le premier qui tombe"

et j'avais trouver une structure d'accueuil qui m'avait proposé un deal du genre :

"vous nous filez 500E tout de suite, nous ont monte votre dossier, et ont espere vous trouvez un boulot plus tard..."

dans le genre j'avait été obligé de leur répondre "et moi de mon coté, j'espere vous regler d'ici un certain temps..." et j'ai tracé ma route.

du coup je m'entraine comme je peut en attendant ...

Lien vers le commentaire
Partager sur d’autres sites

pour commencer à debug, la première chose à faire, c'est de pouvoir contrôler ce qui est lu/écrit.

rajoutes des printf après chaque acquisition/écriture histoire de checker ce qu'il s'est passé.

car pour moi, le problème c'est pas que t'écris en chinois, c'est que t'écris en binaire ^^

par exemple, rien que ton calcul dans le fseek() semble daubé

et, peux-tu nous expliquer ce que fait cet algo ?

tu lis ton fichier

si le nom de la ligne en cours est bon, tu recalcules 'moyenne' et 'partie', puis tu réécris au même endroit (ce qui ne fonctionnera plus si jamais moyenne passe de un à deux chiffres (par ailleurs, le moins goret serait de ne pas réécrire le nom ^^))

sinon, tu vas écrire tes infos actuelles à la fin du fichier (si tu veux gérer plusieurs joueurs, c'est raté, tu calculera pour ton premier, les autres, faudra relire tout le fichier pour faire les calculs).

petite parenthèse: je t'avais parlé plus haut de bufferiser tes fichiers avant de les traiter (pas forcément présenté comme ça, mais le coeur y était).

c'est l'exemple type. Si tu te retrouves à faire de la merde en sortie, c'est que tu te prends la tête sur un algo bancale.

lit tout le fichier, fais tes calculs en mémoire, et garde-les.

si tu veux vraiment tenir le fichier à jour, libre à toi de venir réécrire les résultats régulièrement (à chaque modification du score).

ensuite, changer le tableau (char nom[TAILLE]) en pointeur n'est pas forcément une bonne idée.

un avantage des structures est que tu peux les écrire dans un fichier.

partant de ce principe, si tu veux (par exemple) faire un fichier pour conserver tes scores, mais que tu préfère qu'il ne soit pas directement lisible, tu peux y écrire tes structures. A la relecture, tout sera déjà en place, tu n'aura besoin de rien faire. par contre, écrire un pointeurs (j'ai pas essayé, mais j'en suis convaincu) reviendra à écrire l'adresse en mémoire du contenu, et ne permet donc pas de conserver l'information. il faut donc de préférence utiliser un tableau statique dans ce cas.

typedef struct s_joueur{
char   name[NAME_LENGTH];
unsigned int	score;
unsigned int	moyenne;
}	ply;

int	main(void)
{
ply	*joueurs; /* au passage, on va créer un tableau de joueurs, pour simplifier les choses */
int	 x, y;

/* acquisition des joueurs */
joueurs = malloc(sizeof(*joueurs) * nombre_joueurs);
for (y = 0; y < nombre_joueurs; y++)
{
	for (x = 0; x < strlen(nouveau_nom); x++) joueurs[y].name[x] = nouveau_nom[x]; joueurs[y].name[x] = 0;
	joueurs[y].score = joueurs[y].moyenne = 0;
}
joueurs[y] = NULL;

/* sauvegarde de la partie */
for (x = 0; joueurs[x]; x++)
	fwrite(scoring, &joueurs[x], sizeof(ply));

/* récupération des score */
while (fread(scoring, &joueurs[x], sizeof(ply))
	x++;
}

(un peu à l'arrache, ça demanderait compilation pour s'assurer du bon fonctionnement)

par contre, pour la réécriture dans un fichier, c'est pas être un goret que de se remettre au début et de réécrire par dessus.

de toute façon, à toi de rajouter le EOF à la fin de ton fichier, la suite n'appartient plus au fichier.

recouvrir l'ancien fichier de '\0' avant de réécrire, c'est un plus. mais ça tient plus d'une politique sécuritaire parano (bien que parfois indispensable).

enfin, je pense pas qu'on arrive à monter "un voyage linguistique pour gros_faignan" ici.

mais pour l'anglais, rien de mieux que du man, et des séries en VO.

Lien vers le commentaire
Partager sur d’autres sites

et, peux-tu nous expliquer ce que fait cet algo ?

en tout cas je peut expliqué ce que j'avais essayer de faire

1/ -j'ouvre mon fichier et je test l'ouverture

2/ -si c'est OK, je m'assure d'etre au debut du fichier et je lit, avec fscanf, chacune des ligne
de mon fichier en bouclant ligne par ligne jusqu'au EOF (et vu que fscanf place les valeur 
lues dans des variables disposant d'espace memoire auto) je me suis dit que c'etait ok niveau buffer

	3/ -si dans l'une de ces ligne formaté lues la valeur contenue dans "joueur.nom" est 
	égale au nom entré par le joueur alors je me replace au debut de la ligne par mon
	fseek(mal_foutu) et j'ecrase toute la ligne par un nouveau fprintf de ma struct
	contenant les nouvelle valeur qui ont été calculée dans x_joueur

4/ -si mon fichier est vide je printf ma struct direct

5/ -fclose pour terminer

par contre je pense pas etre en binaire puisque sous windows pour ouvrir un fichier en binaire il faut rajouter 'b' à la modalité d'ouverture dans fopen()

et puis bon j'ai pas encore finis de travailler sur ton algo mais je comprend pas pourquoi tu code sa :

typedef struct s_joueur{
char   name[NAME_LENGTH];
unsigned int	score;
unsigned int	moyenne;
}	ply;

int	main(void)
{
ply	*joueurs; /* au passage, on va créer un tableau de joueurs, pour simplifier les choses */
int	 x, y;

/*...............................

dans le genre je veut pas te la faire a l'enver mais le code devrait pas se faire comme sa ???

s_joueur *joueurs; //pour creer un pointeur de type s_joueur
*joueurs= &ply;// pour attribuer a ptr "joueurs" l'adresse de ply

???

alors le probleme c'est qu'avec tout le melange je finis par plus savoir quand est ce que je dois preciser adresse (&) ou valeur (*) mais bon je pense que je vais finir par m'y faire

par exemple, rien que ton calcul dans le fseek() semble daubé

pour mon fseek(mal_foutu) le probleme c'est de trouver comment calculé ma valeur de retour arrière de mon curseur pour qu'il arrive au debut de la ligne qui m'interesse et que je veut ecraser. mais sa ne fonctionnera que si ce qu'il y a avant fonctionne.

juste pour infos j'avais tenter de faire un melange de sizeof et de strlen par ce que un sizeof simple de ma struct m'aurait compté , pour:

#define TAILLE 100
struct save_score
{
char nom[TAILLE];
float moyenne;
int partie;
};

sizeof (save_score) = 1octet*100 + 8octet*1 + 4octet*1= 112 octet

ce qui si j'ai pigé le truc n'aurait été valable comme valeur de retour que si tous mes joueur avait entré des prenom de 100 char ce qui est fort peut probable.... mais bon je vais retravailler tout sa

=> PS : @spaz001 bah en fait c'est bien logique que le char *toto="ttt" puisse pas etre modifier (autant pour moi j'ai parler trop vite) puisque a la base le 2 dernier t seront en depassement donc effectivement essayer de les modif ensuite va tenter de faire une ecriture dans un espace memoire non alloué au *toto.

Lien vers le commentaire
Partager sur d’autres sites

=> PS : @spaz001 bah en fait c'est bien logique que le char *toto="ttt" puisse pas etre modifier (autant pour moi j'ai parler trop vite) puisque a la base le 2 dernier t seront en depassement donc effectivement essayer de les modif ensuite va tenter de faire une ecriture dans un espace memoire non alloué au *toto.

Ca n'a rien a voir avec ça.

"const" n'est qu'un qualifieur, pour aider en indiquant au compilateur ce qui est possible ou pas. Celui-ci est d'ailleurs enlevable.

toto est un pointeur, sur char. Mais "ttt" aussi, c'est un const char *. La différence c'est que ces 4 caractères seront dans une section mémoire qui n'est pas modifiable, et c'est pour ça que ça plante.

Tu peux faire le test toi même en faisant un strdup de toto dans un nouveau pointeur, et en faisant le test d'écriture sur ce nouveau pointeur, tu verras que ça marcheras cette fois-ci.

Lien vers le commentaire
Partager sur d’autres sites

ouais mais je vois pas pourquoi un char *toto est contenue en zone memoire non modifiable, c'est vrai que je suis peut etre un peut pointillieux, mais d'un autre coté si j'avais voulu faire en sorte qu'il soit "const" j'aurais pu le mettre moi meme, je comprend pas pourquoi c'est comme sa d'office.

autre chose, j'ai verifier la valeur de char *toto="moto", en faisant un sizeof(toto) et curieusement sizeof = 4. donc j'en conclu :

1/ que l'allocation memoire necessaire c'est faite toute seule

2/ que les tableau ne servent a rien (facon de parler, en tout cas ont peut visiblement s'en passer)

et que pour regler ce probleme de modification du *toto ont peut utiliser strdup(), comme tu l'expliquait plus haut ce qui regle par la meme occasion le probleme de free ^^.

par contre je vois pas trop l'interet de free() en manuel - pour l'instant - puisqu'apriori, quand je fais pas de malloc la machine s'en charge toute seule (je veut pas jouer les faignasse mais c'est autant d'instruction, et donc autant de probleme en moins, si ce n'est le plaisir de faire des truc compliquer... mais quand meme)

en plus je comprend pas non-plus pourquoi le malloc qui à été fait dans strdup() permet de free(toto).... (et curieusement j'ai pas reussi a trouver strdup dans les man des libs standard sur cplusplus.com, tout comme _strdup que mon compilo m'invite à utiliser)

Lien vers le commentaire
Partager sur d’autres sites

ouais mais je vois pas pourquoi un char *toto est contenue en zone memoire non modifiable, c'est vrai que je suis peut etre un peut pointillieux, mais d'un autre coté si j'avais voulu faire en sorte qu'il soit "const" j'aurais pu le mettre moi meme, je comprend pas pourquoi c'est comme sa d'office.

autre chose, j'ai verifier la valeur de char *toto="moto", en faisant un sizeof(toto) et curieusement sizeof = 4. donc j'en conclu :

1/ que l'allocation memoire necessaire c'est faite toute seule

2/ que les tableau ne servent a rien (facon de parler, en tout cas ont peut visiblement s'en passer)

et que pour regler ce probleme de modification du *toto ont peut utiliser strdup(), comme tu l'expliquait plus haut ce qui regle par la meme occasion le probleme de free ^^.

par contre je vois pas trop l'interet de free() en manuel - pour l'instant - puisqu'apriori, quand je fais pas de malloc la machine s'en charge toute seule (je veut pas jouer les faignasse mais c'est autant d'instruction, et donc autant de probleme en moins, si ce n'est le plaisir de faire des truc compliquer... mais quand meme)

en plus je comprend pas non-plus pourquoi le malloc qui à été fait dans strdup() permet de free(toto).... (et curieusement j'ai pas reussi a trouver strdup dans les man des libs standard sur cplusplus.com, tout comme _strdup que mon compilo m'invite à utiliser)

Ce n'est pas toto qui pointe vers une zone non modifiable, c'est "test", "test" EST un pointeur, au meme titre que toto. Tu ne fais que recopier l'adresse pointée par "test" dans toto.

Sur un proc 32 bits, les adresses font 32 bits, soit 4 octets. Tout les sizeof(X*) renvoit donc 4.

char * toto = "test";
toto[0] = 'b'; /* Violation d'ecriture */

char * toto = strdup("test");
toto[0] = 'b'; /* OK, toto pointe vers une autre chaine que "test", et dans le tas, donc modifiable */
free(toto);

Le seul intérêt à free en manuel, c'est de faire les choses proprement quand on a malloc en manuel.

Les programmes avec que de l'allocation statique, ca n'existe plus beaucoup, car cela limite fortement les possibilités.

Lien vers le commentaire
Partager sur d’autres sites

Ce n'est pas toto qui pointe vers une zone non modifiable, c'est "test", "test" EST un pointeur, au meme titre que toto. Tu ne fais que recopier l'adresse pointée par "test" dans toto.

Sur un proc 32 bits, les adresses font 32 bits, soit 4 octets. Tout les sizeof(X*) renvoit donc 4.

ok pour sizeof j'ai tester et effectivement sa colle avec ce que tu me dit, par contre de la a comprendre comment "test" (qui est donc une chaine de caractère attribué au pointeur *toto) peut etre elle meme un pointeur (pointeur sur quoi ? sur elle meme ?)

nan franchement la je suis perdu ...... :transpi:

pour avoir un pointeur je suis censé le déclarer, comment ce "test" pourrait s'allouer de l'espace memoire tout seul ???

par contre pour le tas, après avoir fait un tour sur le wiki, j'ai rien compris, si ce n'est pourquoi mephisto ma conseiller de plancher l'algo, ce que je vais surement devoir faire plus tot que prevu.

mais bon histoire de pas me perdre, et de pes mettre la charrue avant les beuh..., je verrais sa peut etre un peut plus tard, la l'objectif c'est surtout de bien comprendre :

les FILE*, les structure et malloc

Lien vers le commentaire
Partager sur d’autres sites

Ce n'est pas toto qui pointe vers une zone non modifiable, c'est "test", "test" EST un pointeur, au meme titre que toto. Tu ne fais que recopier l'adresse pointée par "test" dans toto.

Sur un proc 32 bits, les adresses font 32 bits, soit 4 octets. Tout les sizeof(X*) renvoit donc 4.

ok pour sizeof j'ai tester et effectivement sa colle avec ce que tu me dit, par contre de la a comprendre comment "test" (qui est donc une chaine de caractère attribué au pointeur *toto) peut etre elle meme un pointeur (pointeur sur quoi ? sur elle meme ?)

nan franchement la je suis perdu ...... ;)

pour avoir un pointeur je suis censé le déclarer, comment ce "test" pourrait s'allouer de l'espace memoire tout seul ???

par contre pour le tas, après avoir fait un tour sur le wiki, j'ai rien compris, si ce n'est pourquoi mephisto ma conseiller de plancher l'algo, ce que je vais surement devoir faire plus tot que prevu.

mais bon histoire de pas me perdre, et de pes mettre la charrue avant les beuh..., je verrais sa peut etre un peut plus tard, la l'objectif c'est surtout de bien comprendre :

les FILE*, les structure et malloc

Je pensais bien que tu avais un léger problème de ce côté là, je vais tenter d'expliquer ^^

Quand tu écris "test", ton compilateur va, dans ton programme, mettre en dur dans une section spéciale, la chaine de caractères 'test\0', et partout ou tu vas écrire "test", le compilo saura que c'est l'adresse de cette chaine spéciale.

Ensuite, cette adresse, toi tu la copies dans toto. Ce n'est absolument pas ton char * toto qui crée la chaîne "test", toto n'est qu'un pointeur, il ne fait que pointer, il ne crée, déclare ni instancie quoi que ce soit.

Imagine 2 zones mémoires dans ton prog, une où les données sont en lecture seule ( zone A ), car ce sont des constantes ("test", 2, 1.0f, ...), et une autre où sont situées tes variables (toto, i, j, ...) ( zone B )

( ce n'est pas comme ça que ça fonctionne mais c'est pour schématiser )

Prenons l'exemple : int i = 5;

i est dans la zone B, 5 est dans la zone A. Le 5 de la zone A est copié en B, dans i. i est modifiable, car dans la zone B, je peux écrire i++.

Maintenant : char * toto = "test";

toto (l'adresse pointée par toto) est dans la zone B, "test" est dans la zone A.

La chaîne "test" N'est PAS copié dans toto, dans la zone A, ce qui est copié c'est son adresse mémoire.

toto est modifiable, car dans la zone B, je peux écrire toto++. Le problème c'est que la zone mémoire vers laquelle pointe toto, elle, n'est PAS modifiable, car dans la zone A.

Pour que toto pointe vers une zone modifiable, il faut absolument copier soit-même la chaîne de caractères dans une zone mémoire dans la zone B.

- char toto[5]; strcpy(toto,"test");

- char * toto = malloc(5*sizeof(char)); strcpy(toto,"test");

- char * toto = strdup("test");

j'espère ne pas t'avoir embrouillé encore plus :craint:

Lien vers le commentaire
Partager sur d’autres sites

j'espère ne pas t'avoir embrouillé encore plus :francais:

si,... c'est vilain :D

mais dans le principe j'ai compris les explication.

ce que je comprend pas c'est pourquoi le "test" de :

char *toto="test"

se met (tout seul, hein...!, c'est pas moi qui lui est dit de faire sa... :pleure: au passage) dans la zone A (non modifiable) alors qu'il aurait très bien pu se mettre en zone B (modifiable) et faire pointer *toto vers sont adresse memoire en zone B.

et pareil pour

int I=5

pourquoi est ce que I contient "5" copie de "5" depuis la zone A dans la zone B alors que "5" aurait très bien pu etre ecrit directement dans la zone B.

je contest pas, il y a surement un interet, mais, je le comprend pas, et puis c'est quelque part en contradiction avec le principe qu'on nous explique au debut comme quoi ont va etre obligé de lui dire tout ce qu'il à a faire.

@ mephisto : bon alors franchement +1 pour la technique du printf en debug, c'est plutot long, mais sa m'a permis de comprendre plein de truc qui merdouillait dans tout les sens dans mon fichier

sinon j'ai commencer a reprende ton algo d'acquisition des joueur, et je comprend pas pourquoi tu les mets tous a 0, 2 par 2 dans la boucle, et encore mois pourquoi tu met toutes la structure a NULL une fois que t'es sortit de la boucle.

et pour revenir la dessus

typedef struct s_joueur{
char   name[NAME_LENGTH];
unsigned int	score;
unsigned int	moyenne;
}	ply;

int	main(void)
{
ply	*joueurs;

pour la declaration de ton pointeur * joueur, est ce que sa revient au meme que sa ?

s_joueur *joueurs; //pour creer un pointeur de type s_joueur
*joueurs= &ply;// pour attribuer a ptr "joueurs" l'adresse de ply

et si j'ai bien pigé ce que fait ton code, dit moi si je me trompe, il creer un tableau de joueur, stock les score pour chaque joueur puis les ecrit joueur par joueur dans le fichier.

si c'est bien sa, :chinois: dsl mais je croit que je t'ai induit en erreur, et c'est vrai que j'aurais peut etre pu etre plus precis en parlant de ce que voulais atteindre comme resultat.

mon objectif c'est de trouver comment construire un algo qui lise les valeur des score qui ont été attribuer à différent joueurs, identifier par leurs noms, (les scores sont 1/ moyenne de coups par partie, et 2/ nombre de partie) et sont stocké dans le fichier sous le format fprintf("%s %f %d",...)

une fois qu'une fonction spécifique a trouver la ligne formaté correspondant au joueur qui vient de finir sa partie (et donc de rentrer sont nom) une autre fonction fait une moyenne des resultat actuels et anterieur sur le champ "moyenne" ("%f") et fait une addition du nombre de partie faite par le joueur puis, réécrit la ligne mise a jour dans le fichier.

bon c'est vrai qu'au depart j'ai peut etre un peut fait l'boeuf en prenant les struct pour des enregistrement de base de données (ouep, non ptete pas quand meme, mais presque) :francais:

enfin voila l'idée.

mais pour le principe du printf pour la debug sa m'a permis de découvir des bug dont j'aurais meme pas soupçonné l'existence. :dd:

enfin pour terminé j'ai ouvert un nouveau topic pour tout les probleme de fichier qui visiblement vont etre plus nombreux que prévu, histoire que ce topic reste concentré sur les pointeur et sur tout ce qui y est lié :

structure, malloc et tableau

si vous voulez jeter une piti coup d'oeil au topic sur les fichier en C, c'est par là

Lien vers le commentaire
Partager sur d’autres sites

sinon j'ai commencer a reprende ton algo d'acquisition des joueur, et je comprend pas pourquoi tu les mets tous a 0, 2 par 2 dans la boucle
je vois pas bien ce que tu veux dire, tu parles du for() où j'initialise le nom du joueur ? l'instruction qui met à un caractère à 0 n'est appelé qu'en fin de boucle

un for sans accolades n'exécute que l'instruction qui le succède, et donc pas la suivante, même si elles sont sur un même ligne.

et encore mois pourquoi tu met toutes la structure a NULL une fois que t'es sortit de la boucle.
une fois sortie de la boucle (au même titre que si cette boucle recopiait un char*), je set mon dernier élément à 0.

Ainsi, pour x = 0, je parcours joueurs[x], et lorsque !joueurs[x], je sais que j'ai atteins la fin de ma liste

il s'agit de pointeurs, si je n'avais pas précisé le 0, joueurs[x] m'aurait alors envoyé sur l'emplacement consécutif de ma mémoire, et un appel à joueus[x]->score m'aurait renvoyé une valeur aberrante (puisque déjà présente en mémoire, avant même qu'on n'ait lancé notre programme)

pour la declaration de ton pointeur * joueur, est ce que sa revient au meme que sa ?

s_joueur *joueurs; //pour creer un pointeur de type s_joueur
*joueurs= &ply;// pour attribuer a ptr "joueurs" l'adresse de ply

pas loin.

ta première ligne est vraie. (on crée un pointeur de type struct s_joueur, ou t_ply)

par contre:

joueurs = &ply;

-> joueurs est un pointeur, on peut lui assigner l'adresse d'une structure de même type.

mais *joueurs est l'élément pointé par joueurs[0], donc, le contenu la struct s_joueur. je ne suis pas certain de ce qu'il se passerait dans ce cas, mais à priori, l'adresse de ply se retrouverait en premier caractère de la chaine du nom du joueur (ou quelque part pas loin).

et si j'ai bien pigé ce que fait ton code, dit moi si je me trompe, il creer un tableau de joueur, stock les score pour chaque joueur puis les ecrit joueur par joueur dans le fichier.
là, on est d'accord ^^
si c'est bien sa, :craint: dsl mais je croit que je t'ai induit en erreur, et c'est vrai que j'aurais peut etre pu etre plus precis en parlant de ce que voulais atteindre comme resultat.

mon objectif c'est de trouver comment construire un algo qui lise les valeur des score qui ont été attribuer à différent joueurs, identifier par leurs noms, (les scores sont 1/ moyenne de coups par partie, et 2/ nombre de partie) et sont stocké dans le fichier sous le format fprintf("%s %f %d",...)

une fois qu'une fonction spécifique a trouver la ligne formaté correspondant au joueur qui vient de finir sa partie (et donc de rentrer sont nom) une autre fonction fait une moyenne des resultat actuels et anterieur sur le champ "moyenne" ("%f") et fait une addition du nombre de partie faite par le joueur puis, réécrit la ligne mise a jour dans le fichier.

bon c'est vrai qu'au depart j'ai peut etre un peut fait l'boeuf en prenant les struct pour des enregistrement de base de données (ouep, non ptete pas quand meme, mais presque) :transpi:

enfin voila l'idée.

ben, dans l'idée, voilà comment procéder:
{
/*
 * la lecture
 */

int fd, x, len, slen;
char *buf, *tmp;

fd = open("file.txt", O_RDONLY); // pas la peine de te faire chier avec des FILE*, fprintf, fscanf, ...
slen = 0;
buf = malloc(sizeof(char*) * 420);
tmp = malloc(sizeof(char*) * 420);
if (!tmp || !buf)
	exit(fprintf(stderr, "ça sent le segfault\n") ? -1 : -1); // petite gestion d'erreur, histoire d'être propre
if (fd > 2)
{
	while ((len = read(fd, &tmp, 42))) /* tant que je lis quelque chose */
	{
		for (x = 0; x < len; x++) buf[slen + x] = tmp[x]; buf[slen + x] = 0 // je remplie mon buffer avec ce que j'ai lu
		for (x = 0; buf[x]; x++)
		{
			if (!strncmp(nom_joueur, &buf[x], strlen(nom_joueur)) break; // si on a trouvé notre joueur, on sort ce ce for()
			else if (10 == buf[x]) // un retour à la ligne
			{ // le nom de joueur ayant déjà été lu, on peut en déduire qu'il ne match pas, et peut être retiré.
				for (slen = 0, x++; slen < x; slen++) buf[slen] = buf[x]; buf[slen] = 0; // slen est alors correctement positionné pour lire les 42 prochains caractères de ton fichier
				x = 0; // on se remet en début de chaîne, au cas où le nom qui nous intéresse se trouve sur la ligne suivante, qui a très bien pu être déjà bufferisé (une lecture de 42, c'est potentiellement 42 lignes lues ^^
			}
		}
		if (buf[x]) // si l'on a trouvé notre joueur
		{
			int fspc, sspc;

			for (fspc = sspc = 0; buf[x] && 10 != buf[x]; x++)
			{
				if ((32 == buf[x] || 9 == buf[x]) && !fspc) // premier espace/tabulation
					fspc = x;
				else if ((32 == buf[x] || 9 = buf[x]) && fspc) // second espace
					sspc = x;
			} // je peux maintenant récupérer les valeurs qui m'intéressent
			if (10 = buf[x]) // le joueur est trouvé, mais la ligne ne contient pas deux espaces, et ne peut donc pas contenir ce qu'on cherche
			{
				fprintf(stderr, "ligne incorrecte ignorée (%.25s)\n", &buf[slen]);
				slen = x + 1;
				continue;
			}
			if (!buf[x] || !fspc || !sspc)
				continue; // si je n'ai pas bufferisé suffisemment pour tout récupérer, on va en lire un peu plus
			for (len = 0, slen = fspc + 1; len < sspc; len++, slen++) tmp[len] = buf[slen]; tmp[len] = 0; // on récupère le score
			*score = atof(tmp);
			for (len = 0, slen = sspc + 1; buf[slen]; len++, slen++) tmp[len] = buf[slen]; tmp[len] = 0 // puis la moyenne
			*moyenne = atoi(tmp);
			break;
		}
	}
	printf("joueur:%s moyenne de %.2f pour %d parties\n", nom_joueur, *moyenne, *score);
}
else
	exit (fprintf(stderr, "impossible d'ouvrir le fichier de scores\n") ? -1 : -1);
}

à nouveau, pas testé, ni même compilé, et plein de lacunes (je ne vérifie pas grand chose, et ais une confiance aveugle en la structure du fichier) ((et c'est codé en plusieurs fois, je peux pas assurer que l'algo soit correct, mais t'as les grandes lignes))

si j'utilise *score et *moyenne, c'est que, ayant plusieurs valeurs à récupérer (en supposant les récupérer dans une fonction parente), j'ai donc supposé que l'appel à la fonction de lecture des scores se ferait ainsi: getscore(nom_joueur, &moyenne_recherchée, &nbparties_recherché);

l'avantage d'envoyer les adresses d'un float et d'un int à une même fonction est que ça me permet de récupérer dans ces variables les valeurs assignées lors de leur utilisation dans la fonction fille.

C'est pas forcément très claire, mais à la longue, tu vas voir, c'est plus simple que se trimballer une structure fake qui ne sert qu'à faire un return de plusieurs valeurs prédéfinies, plus propre que d'utiliser des globales, ... bref... on s'est compris (?)

et pour la fonction qui retourne écrire les nouvelles valeurs dans le fichier, je te laisse plancher dessus ^^

(petit rappel quand même, c'est pas parceque l'ancienne chaîne faisait 40 caractères que la nouvelle n'en fera pas 30)

mais pour le principe du printf pour la debug sa m'a permis de découvir des bug dont j'aurais meme pas soupçonné l'existence. :transpi:
jte lfais pas dire.
Lien vers le commentaire
Partager sur d’autres sites

salut

alors tout d'abord petites questions d'ordre generale

je suppose que quand tu ecris sa

(!n_importe_quelle_variable)

sa revient a ecrire sa

(n_importe_quelle_variable==NULL)

dans le sens ou "!" indique différent de n'importe quelle valeur donc NULL.

ensuite, je peut me tromper mais je crois que les fonction asprintf (que tu utilise dans l'autre code, mais bon c'est juste histoire de, vue que j'ai pas trouver d'equivalent), les fonction open, read et write, n'existe que sous GNU/unix

ce qui je doit l'avouer m'a un peut fait devenir chevre :fumer: (je comprenais pas pourquoi sa fonctionnait pas)

ensuite dans

tmp=malloc(sizeof(char*)*420)

pourquoi 420 ??? (bon c'est vrais que c'est 10 fois 42 mais dans ce cas pourquoi 42) :sm: surement un peut bete comme question mais vue que j'ai pas trouver d'explication...

histoire d'essayer de prendre le probleme dans l'autre sens y aurait pas une methode pour structurer le fichier de telle sorte que chaque données soit facile d'acces.

tu me parlait des fichier binaire, et c'est vrai que dans ce cas j'ai pas spécialement besoin que le joueur ai acces au fichier en direct, donc si sa me permettait de lui faire stocker les variables au passage sa pourrait etre pratique histoire de les recupérer ensuite, mais bon ce serait surement trop facile.

j'ai bien chercher quelque truc sur les fichier binaire genre tuto ou autre mais j'ai pas trouver grand chose concernant l'utilité et les différence entre binaire et texte.

enfin dernier point, pour en revenir a ce que tu me disais concernant le probleme d'écriture suite a lecture dans le fichier si la longeur de ma chaine est différnte (exemple si ma ligne de départ fait 30 caractère et celle que j'ecrit par dessus n'en fait que 20) bas dans ce cas j'ai effectivement rien trouver de concret.

disons que je suis partie du principe que la ligne qui viendrait ecraser la précedente serait forcement plus longue (le nom du joueur restant inchangé et le nombre de partie ayant augmenter.

mais effectivement dans le cas contraire j'imagine que le relicat de ligne restant serait placé a la ligne suivante par le '\n' de la ligne ecrasante.

donc pareil si ya une autre solution qui permet d'eviter tout ces problemes sa m'interesse. :byebye:

et pour le (les) codes que tu m'a filer j'ai pas tout compris mais j'y travail

Lien vers le commentaire
Partager sur d’autres sites

je suppose que quand tu ecris sa

(!n_importe_quelle_variable)

sa revient a ecrire sa

(n_importe_quelle_variable==NULL)

dans le sens ou "!" indique différent de n'importe quelle valeur donc NULL.

exactement
ensuite, je peut me tromper mais je crois que les fonction asprintf (que tu utilise dans l'autre code, mais bon c'est juste histoire de, vue que j'ai pas trouver d'equivalent), les fonction open, read et write, n'existe que sous GNU/unix
euh... désolé, vraiment pas habitué à winwin
tmp=malloc(sizeof(char*)*420)

pourquoi 420 ??? (bon c'est vrais que c'est 10 fois 42 mais dans ce cas pourquoi 42) :mad2: surement un peut bete comme question mais vue que j'ai pas trouver d'explication...

avant tout pour le 10x42, ensuite pour la signification de 420 (ceux qui m'auront compris, tant mieux pour vous), et parceque je suppose que ce sera suffisant pour faire buffer (oui, c'est mal !!! mais j'aurais pu/du fstat mon fichier, récupérer sa taille, et malloc mes buffer ainsi).
histoire d'essayer de prendre le probleme dans l'autre sens y aurait pas une methode pour structurer le fichier de telle sorte que chaque données soit facile d'acces.

tu me parlait des fichier binaire, et c'est vrai que dans ce cas j'ai pas spécialement besoin que le joueur ai acces au fichier en direct, donc si sa me permettait de lui faire stocker les variables au passage sa pourrait etre pratique histoire de les recupérer ensuite, mais bon ce serait surement trop facile.

j'ai bien chercher quelque truc sur les fichier binaire genre tuto ou autre mais j'ai pas trouver grand chose concernant l'utilité et les différence entre binaire et texte.

en effet, c'est imaginable.

1) soit tu met tout en structure, tu écris tes struct les unes à la suite des autres pour les sauver, et tu repasse les lire pour récupérer leur contenu

2) soit tu sérialise/désérialise tes structures (c'est plus utilisé en objet, mais ça a aussi son intérêt en C)

enfin dernier point, pour en revenir a ce que tu me disais concernant le probleme d'écriture suite a lecture dans le fichier si la longeur de ma chaine est différnte (exemple si ma ligne de départ fait 30 caractère et celle que j'ecrit par dessus n'en fait que 20) bas dans ce cas j'ai effectivement rien trouver de concret.

disons que je suis partie du principe que la ligne qui viendrait ecraser la précedente serait forcement plus longue (le nom du joueur restant inchangé et le nombre de partie ayant augmenter.

mais effectivement dans le cas contraire j'imagine que le relicat de ligne restant serait placé a la ligne suivante par le '\n' de la ligne ecrasante.

donc pareil si ya une autre solution qui permet d'eviter tout ces problemes sa m'interesse. :smack:

la seule possibilité qui me saute aux yeux: tu bufferise tout le fichier, et tu réécris tout à la fin (ou après chaque modif, si tu veux te faire chier ;))
et pour le (les) codes que tu m'a filer j'ai pas tout compris mais j'y travail
c'est plus pour le principe

faut pas s'y fier, je l'ai précisé: c'est du code jamais compilé / pondu à l'arrache, tandis que je suis supposé bosser (mais... procrastination).

Lien vers le commentaire
Partager sur d’autres sites

en effet, c'est imaginable.

1) soit tu met tout en structure, tu écris tes struct les unes à la suite des autres pour les sauver, et tu repasse les lire pour récupérer leur contenu

2) soit tu sérialise/désérialise tes structures (c'est plus utilisé en objet, mais ça a aussi son intérêt en C)

j'ai bien chercher quelque truc sur la serialisation mais sa a l'air loin d'etre abordable.

et puis d'autre part ecrire les valeur contenue dans les structures (bref... mes string ou mes nombres) doit etre assez différent d'ecrire les structure liées aux valeurs... et pareil j'ai pas trouver grand chose a part sa fichier texte et binaire (le debut) mais forcement la partie codage concerne le VB.

alors sinon j'ai peut etre trouver autre chose en utilisant

1/ while(feof()) et

2/ deux structure au lieu d'une; je m'explique:

1/ je crée 2 strucure : 1 qui stock nom[], moyenne et partie de la partie en cours, et l'autre qui stock, grosso merdo, le numero de ma ligne, le nombre de caractère, le nom[], la moyenne et la partie contenue dans le fichier

2/je malloc() un pointeur de struct n°2 pour qu'il creer autant de ligne que contenue dans le fichier

3/je lit mon fichier ligne par ligne en rentrant les informations dans ma 2e structure (je sui en train de plancher sur l'algo qui me permettra de lire en meme temps : nombre de caractère par ligne, nombre de ligne - qui correspondra à l'indice de mon tableau(ou de '\n') et chaine formaté comme fscanf() -:fumer: ouaip je vais déposer un copyright pour l'expression "repositionnement intempestif dans un fichier"

4/une fois que mon tableau de struct 2 est rempli avec toutes les lignes, je fais mon strcmp() pour trouver le nom qui m'interesse puis je fait mes operation sur les case qui m'interesse grace à la struct n°1

5/j'utilise mes infos stocké sur le nombre de caractère par ligne pour me positionner au bon endroit de mon fichier

6/je printf par dessus

l'ideal serait d'avoir une fonction delete() qui supprimerai le contenue du fichier et m'epargnerai ces maudits repositionnement mais pas de bol pour sa tout ce que j'ai trouver c'est fopen(stream,w) qui m'oblige à fermer le fichier avant et d'après ce que j'ai pu verifer, les information bufferiser seront automatiquement vider a sa fermeture....

sinon peut etre une boucle fputc("",scores) jusqu'a EOF, mais rien qu'a me lire sa a l'air abominable. :pleure:

enfin dans ton code quant tu test un caractère de controle tu fais, par exemple:

if(32==buf[x])

comment le programme fais pour savoir qu'il sagit de l'ascii correspondant et pas du chiffre 32, j'avoue que sa m'intrigue

tandis que je suis supposé bosser (mais... procrastination).
procrastination : "Tendance à différer, à remettre au lendemain une décision ou l'exécution de quelque chose.

procrastinateur : "Les atermoyeurs, procrastinateurs et lambins de mon acabit sont justement de ceux qui ne finissent rien et même ne commencent pas davantage (Amiel, Journal, 1866, p.455)".

en somme... une sorte de gros faignan :p

faut qu'on pense a ouvrir un clan

Lien vers le commentaire
Partager sur d’autres sites

enfin dans ton code quant tu test un caractère de controle tu fais, par exemple:

if(32==buf[x])

comment le programme fais pour savoir qu'il sagit de l'ascii correspondant et pas du chiffre 32, j'avoue que sa m'intrigue

Parce qu'un caractère ascii, c'est quoi ? c'est pas un nombre ?

Lien vers le commentaire
Partager sur d’autres sites

mouai... la question pique les yeux :)

c'est un caractère

donc, un code ascii lui correspond

et celui de l'espace, c'est 32

et pour ton algo, j'ai l'impression que tu te prends la tête pour pas grand chose.

pourquoi deux structures ?

le problème de mettre à jour ton fichier (on en a déjà parlé), c'est qu'il faudra tout réécrire, si tu veux être sûr de ne pas laisser de merde.

donc, tu as tout intérêt à ne garder qu'une seule occurrence de tes données (pas la peine de se garder un duplicata juste pour l'écrire en fichier)

à la rigueur, fais-toi un save_scores() (peu importe le nom), qui parcours tes structures et soit les écrits en dur, soit formate leur contenu de manière lisible ("nom score nb_parties", ou la sérialisation)

Lien vers le commentaire
Partager sur d’autres sites

et pour ton algo, j'ai l'impression que tu te prends la tête pour pas grand chose.

pourquoi deux structures ?

En fait il y en aurait surtout une d'utile, la N°2, l'autre est juste la pour stocker les elements de la partie en cours, mais des variables suffirait.

le problème de mettre à jour ton fichier (on en a déjà parlé), c'est qu'il faudra tout réécrire, si tu veux être sûr de ne pas laisser de merde.

ok d'accord mais pour sa il faut que je le vide avant.

[EDIT 5] solution que j'ai finalement choisie c'est plus propre, avec un fopen(...,W+) sa fonctionne

donc, tu as tout intérêt à ne garder qu'une seule occurrence de tes données (pas la peine de se garder un duplicata juste pour l'écrire en fichier)

pourquoi un duplicata ???

je met tout les element dans ma struct, fait mes operation puis vide le fichier et remet les element dedans

[EDIT 5]

effectivement vue que j'ai plus besoins de me prendre la tete avec le positionnement dans le fichier une seul struct suffit parfaitement

à la rigueur, fais-toi un save_scores() (peu importe le nom), qui parcours tes structures et soit les écrits en dur, soit formate leur contenu de manière lisible ("nom score nb_parties", ou la sérialisation)

serialisation je desespere pas mais pour l'instant sa a surtout l'air inbitable

et comment sa une fonction qui formate la strucure ??? elle est a priori deja formaté par le fprintf non ???

[EDIT] :

et concernant la conjonctivite, ce que je voulais dire c'est que si j'avait u par exemple le nombre 32 de contenue dans ma string (allons savoir pourquoi..) le programme aurais pas pu faire la différence, mais je vient de voir la bourde puisque en fait sa correspondrait aux caractère 3 et 2

[EDIT 5 (jais supprimmé les autres c'etait trop long)]

bon alors je suis arrivé a un resultat qui fonctionne mais c'est pas encore trop sa !!!

histoire de trouver une solution je voulais savoir si il y a un moyen de connaitre la taille d'un malloc ?

je m'explique, je fais le malloc d'un pointeur de struct et histoire de verifier que malloc m'a bien alloué ce que je lui ai demandé (ce qui n'est visiblement pas toujours le cas) je me suis di que je pourrais faire comme sa :

	xjoueur=malloc(coef*sizeof(*xjoueur));//coef etant dans mon exemple egale a 9
/*****code*******/
for(i=0;xjoueur[i].nom;i++)
{
	printf("\n%s %f %d",xjoueur[i].nom,xjoueur[i].moyenne,xjoueur[i].partie);
}

mais pas de bol sa marche pas, il me sort une boucle infinie (ou presque) et me dit genre au bout de 100 "lignes" (donc 91 de trop) qu'il est en read access violation...

chercher l'erreur.... y a t'il une autre solution???

Lien vers le commentaire
Partager sur d’autres sites

malloc n'initialise aucune donnée.

donc, c'est normal de partir en boucle infinie en parcourant ton bordel juste après malloc.

j'ai fait un test avec un memset dans la boucle mais c'est pareil

[EDIT]

et au passage je vient de faire le test avec calloc, idem sauf qu'en plus j'ai pas d'initialisation.

Lien vers le commentaire
Partager sur d’autres sites

mais sérieux, tu parcours un tableau là, un i < coef et on en parle plus !

A supposer dans le monde de l'hypothétique que ta mémoire serait rempli correctement pour ta boucle, tu sort de ta boucle en lisant en dehors d'un espace mémoire alloué

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...