Bonjour tout le monde,

Je suis occupé à m'entraîner sur les structures dynamiques.

J'ai deux structures :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
typedef struct {
 
	char* NomL; //on indique ici que l'on ne sait pas combien de caractère il faut pour les différens noms de lune
	double Rayon;
}Lune;
 
typedef struct
{
	char* NomP;
	double RayonP;
	Lune* TLune;  //on indique ici avec l'* qu'on ne sait pas combien de lune il y'aura
} TPlanets;
J'ai créé une variable dynamique de type TPlanets :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
TPlanets* TPlanetsLunes;
J'arrive sans problème à remplir la valeur du Nom de la terre se trouvant dans la structure :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
		TPlanetsLunes[i].NomP = (char*)malloc((strlen(NomPl)+1)*sizeof(char));
 
		if (TPlanetsLune.NomP == NULL)
			{
				printf("\nErreur d'allocation de mémoire\n");
				break;
			}
 
		//je ne dois pas mettre d'indice car c'est la copie de la structure.
		strcpy(TPlanetsLunes[i].NomP,NomPl);
Par contre, je n'arrive pas à remplir le nom de la lune.

Avec ceci :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
TPlanetsLunes[i].TLune[i].NomL = (char*)malloc((strlen(NomLune)+1)*sizeof(char));
j'obtiens ce message d'erreur :

unhandled exception in Astronomie2 ... Access Violation.

Voyez-vous ce qu'il se passe ?

Est-ce que je dois allouer la structure Lune ?

Voici l'entierté de mon code.

Merci à tous pour votre aide.

beegees

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#include <BasicConsole.h>
 
typedef struct {
 
	char* NomL; //on indique ici que l'on ne sait pas combien de caractère il faut pour les différens noms de lune
	double Rayon;
}Lune;
 
typedef struct
{
	char* NomP;
	double RayonP;
	Lune* TLune;  //on indique ici avec l'* qu'on ne sait pas combien de lune il y'aura
} TPlanets;
 
 
 
 
bool	AllocMemStructure(char* NomFichier, TPlanets*& TPlanetsLunes, int& Taille);
bool	DiviserLigne(const char* NomFichier, const Taille,TPlanets*& TPlanetsLunes,TPlanets TPlanetsLune);
char	TraitementLunes(int Position, char* NomFichier, char* NomLune);
 
void main()
{
 
	int Taille = 0;
 
	TPlanets* TPlanetsLunes;//on ne sait pas encore la Taille de cette structure, c'est pourqoi
							//on va directement à la fonction AllocMemStructures
	TPlanets TPlanetsLune; //on crée une copie de la structure pour ne pas perdre l'adresse originale
 
 
 
 
 
	if(!AllocMemStructure("syssol.txt",TPlanetsLunes, Taille))printf("Fichier introuvable");
	if(!DiviserLigne("syssol.txt", Taille,TPlanetsLunes,TPlanetsLune))printf("Fichier introuvable");
 
 
 
 
}
 
//Fonction qui ne sert qu''à allouer de la mémoire pour la struture.
//le nombre de fois qu'il passera dans la boucle for sera le nombre de structure que j'aurai besoin
bool	AllocMemStructure(char* NomFichier, TPlanets*& TPlanetsLunes, int& Taille)
{
	char Ligne[100];
	int i = 0;
	FILE* Fichier = fopen(NomFichier,"rt");
 
	if(Fichier == NULL) return false;
 
	for(i=0; ((fgets(Ligne,100-1,Fichier))!=NULL);i++)
	{
		printf("%ld\t",i);
		printf("%s\n",Ligne);
	}
 
	Taille = i;
 
	//allocation de mémoire pour la structure :
 
	printf("La taille d'un TPlanets est de %ld\n",sizeof(TPlanets));
 
	TPlanetsLunes = (TPlanets*)malloc(Taille*sizeof(TPlanets));
 
	fclose(Fichier);
	return true;
}
 
bool	DiviserLigne(const char* NomFichier, const Taille,TPlanets*& TPlanetsLunes,TPlanets TPlanetsLune)
{
 
	FILE* Fichier = fopen(NomFichier,"rt");
	char Ligne[100];
	char Type[1];
	char KmP[15];
	double KmPEnDouble;
	int Position = 0; //Je crée Position pour envoyer l'endroit ou la boucle for devra s'arrêter
					  //lorsqu'il regardera le type juste après celui de la lune dans la fonction
					  //TraitementLunes
	char TypeSecondeLigne = 0;
	if(Fichier == NULL) return false;
 
 
 
	char NomPl[25];
	char NomLune[25];
	for(int i=0; ((i<Taille)
			&& fscanf(Fichier,"%c",Type)
				&& (fgets(Ligne,100-1,Fichier)!=NULL));i++)
	{
		Position++;
		printf("Ligne reçue par la fonction %c\t%s",Type,Ligne);
 
		char* PremiereLettre = strchr(Ligne,9);
 
	PremiereLettre = PremiereLettre + 1;
 
 
	int j = 0;
	char * p = NomPl;
	while(*PremiereLettre !=9)
	{
		*p++ = *PremiereLettre++;
 
 
	}
 
	//j'incrémente d'abord *p de 1 (++) puis j'ajoute le code ASCII O
 
	++*p = 0;
 
	//Si la première valeur du tableau vaut P alors c'est une Planète
	if(*Type == 'P')
	{
		//J'alloue de la mémoire pour le nom de la planète si c'est une planète
 
		TPlanetsLunes[i].NomP = (char*)malloc((strlen(NomPl)+1)*sizeof(char));
 
		if (TPlanetsLune.NomP == NULL)
			{
				printf("\nErreur d'allocation de mémoire\n");
				break;
			}
 
		//je ne dois pas mettre d'indice car c'est la copie de la structure.
		strcpy(TPlanetsLunes[i].NomP,NomPl);
	}
 
	TypeSecondeLigne = TraitementLunes(Position,"syssol.txt",NomLune);//Je vais voir si à la prochaine ligne juste après celle que je traite, je vais voir si c'est un L ou un P
 
	if (TypeSecondeLigne == 'L') //si c'est un L, je vais ajouter dans le même tableau de la structure [i]
	{
		//il faut d'abord allouer de la mémoire pour la structure Lune (je pense)
 
		//et ensuite il faut réserver de la mémoire pour le nom de la lune (pas sûr)
			TPlanetsLunes[i].TLune[i].NomL = (char*)malloc((strlen(NomLune)+1)*sizeof(char));
		strcpy(TPlanetsLunes[i].TLune[i].NomL,NomPl);
	}
	PremiereLettre++;
	strcpy(KmP,PremiereLettre);
 
 
	PremiereLettre = strchr(KmP,0);
	//si la lettre juste avant le EOS (0) est différent de 0 (EOS)...
	if(*(PremiereLettre-1)!=0)
	{
		//...Je décrémente l'adresse de PremiereLettre
		PremiereLettre--;
		//Je transforme la valeur (*) se trouvant à l'adresse décrémentée par un 0 (zéro, EOS)
		*PremiereLettre = 0;
	}
 
	//strtod(KmP,KmPEnDouble);	
	//sscanf(KmP,"%lf",&KmPEnDouble);
 
	//strcpy(TPlanetsLune.RayonP,KmPEnDouble);
 
 
	//strcpy(TPlanetsLunes[i].NomP,TPlanetsLune.NomP);
	//strcpy(TPlanetsLunes[i].RayonP,TPlanetsLune.RayonP);
 
	}
 
 
}
 
char	TraitementLunes(int Position, char* NomFichier, char* NomLune)
{
	//dans cette fonction, on va tant qu'on est pas à la valeur de Position, copier dans
	//Ligne la valeur du fichier txt.
	//donc si dans la fonction DiviserLigne i vaut 0, j'envoi Position qui vaut 1,
	//je fait un fgets tant que i est inférieur ou égal à Position, cela va me permettre
	//de tester le premier caractère du tableau Ligne et voir si ça commence par un L ou par un P.
 
	FILE* Fichier = fopen(NomFichier,"rt");
	char Ligne[100];
	int retour = 0; //Je vais retourner le code	ASCII du L ou du P pour informer qu'est-ce qui est le prochain type
 
	if (Fichier !=NULL)
	{
		int i =0;
		char Type[1];
		char* p = NomLune;
 
			for(i=0;
			(i<=Position)
				&&(fgets(Ligne,100-1,Fichier)!=NULL);i++)
		{
 
 
		}
 
			Type[0] = Ligne[0];
 
			if(Type[0] = 76) //Si le Type (Type[0]) vaut L
			{
				char* positionCar = strchr(Ligne,9);
				positionCar++;
 
				while(*positionCar != 9)
				{
					*p++ = *positionCar++; //d'abord j'affecte dans NomLune la valeur (*) de PositionCar ensuite j'incrément les deux variables pointeur
 
				}
 
				*p = 0;
 
 
 
				retour = 76;
 
				return retour;
			}
			else
			{
				retour = 80; //AUTREMENT IL VAUT P
				return retour;
			}
 
 
 
 
	}
	else
	{
		printf("Impossible d'ouvrir le fichier");
	}
}