Bonjour tout le monde,
Je fais un premier exercice qui se passait bien jusqu'à il y'a 2 minutes.
J'obtiens un message d'erreur lors du linking :
La ligne qui pose problème est celle-ci :Linking...
Vehicule3.obj : error LNK2001: unresolved external symbol "private: static bool __cdecl CLeTout::FctnTraiterLigne(class CChargeurFichierTexte const &,void *)" (?FctnTraiterLigne@CLeTout@@CA_NABVCChargeurFichierTexte@@PAX@Z)
Debug/vehicule3.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
car quand je fais "return true", tout se passe bien et je n'obtiens aucun message d'erreur lors de la compilation et du linking.
Code : Sélectionner tout - Visualiser dans une fenêtre à part return Chargeur.Charger(NomFichier,'\t',CLeTout::FctnTraiterLigne,this);
voici mon code : Merci d'avance pour votre aide.
beegees
Voici le fichier qui pose problème (où s'est peut être le chaine.h ou le chaine.cpp) :
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 #include <BasicConsole.h> #include "vehicule3.h" #include "chaine.h" Vehicule3::Vehicule3() :NombreDePlace(0) { } Vehicule3::~Vehicule3() { } CVoiture::CVoiture() :m_VTM(0.0) { } CVoiture::~CVoiture() { } CTabVoitures::CTabVoitures() :m_Nombre(0),m_Tableau(NULL) { } CTabVoitures::~CTabVoitures() { } CLeTout::CLeTout() { } CLeTout::~CLeTout() { } bool CLeTout::Charger(const char* NomFichier) { CChargeurFichierTexte Chargeur; return Chargeur.Charger(NomFichier,'\t',CLeTout::FctnTraiterLigne,this); }
voici le chaine.h :
et voici le chaine.cpp :
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 #ifndef CHAINE_H #define CHAINE_H class CChaine { public: CChaine(); // Constructeur par défaut CChaine(const CChaine& Source); // Constructeur par copie CChaine(const char* UneChaine); // Constructeur spécifique ~CChaine(); // Destructeur const char* Chaine() const; // Accesseur du texte de la chaîne bool EstNull() const; // Accesseur de test sur le texte (m_Chaine == NULL) bool EstVide() const; // Accesseur de test sur le texte (m_Chaine == NULL) || (m_Chaine == "") void Vider(); // Modificateur permettant de supprimer le texte de la chaîne (on revient à NULL) bool Chaine(const char* UneChaine); // Modificateur du texte de la chaîne private: char* m_Chaine; // Membre contenant l'adresse du tableau de caractères alloué dynamiquement }; class CChaineComposee : private CChaine { public: CChaineComposee(); // Constructeur par défaut CChaineComposee(const CChaineComposee& Source); // Constructeur par copie CChaineComposee(const char* UneChaine, char UnSeparateur); // Constructeur spécifique ~CChaineComposee(); // Destructeur long NombreChamps() const; // Accesseur du nombre de champs const char* Champs(long Indice) const; // Accesseur d'un champ bool Definir(const char* UneChaine, char UnSeparateur); // Modificateur permettant de modifier la chaîne et de générer le tableau des champs private: bool Decomposer(char UnSeparateur); // Modificateur permettant de modifier la chaîne et de générer le tableau des champs private: long m_NbrChamps; char** m_Champs; }; //////////////////////////////// // Class CChargeurFichierTexte// //////////////////////////////// class CChargeurFichierTexte : public CChaineComposee /*Donc en fait cette classe CChargeurFichierTexte à un moment donné ce qu'elle va contenir comme information se sont les données d'une ligne mais déjà décomposée, sont but s'est d'arriver à lire une ligne du fichier texte et de la décomposer automatiquement et donc en servant des fonctionnalités publiques de la classe et bien on aura la possibilité de savoir ce qu'il y'avait comme information sur la ligne (le nombre de champs et les valeurs sous forme de chaîne de caractère des différents champs) et ce qu'elle fournira en plus s'est une méthode de chargement où on peut passer le nom du fichier et la fonction à appeler pour pouvoir traiter les données d'une ligne puisque le but de la fonction charger s'est de : - lire une ligne - d'appeler la fonction passer par celui qui utilise cette classe là - et ensuite d'exécuter cette fonction - et ensuite de passer à la lecture de la ligne suivante et ce jusqu'à la fin du fichier. */ { public: CChargeurFichierTexte(); ~CChargeurFichierTexte(); bool Charger(const char* NomFichier, char UnSeparateur, bool (* FctnTraiterLigne)(const CChargeurFichierTexte&, void*), void* Contexte); private: }; #endif//CHAINE_H
et pour être complet, voici le main :
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 #include <BasicConsole.h> #include "chaine.h" #include "chaine.h" //////////////////// // Classe CChaine // //////////////////// CChaine::CChaine() //constructeur par défaut :m_Chaine(NULL) { } CChaine::CChaine(const CChaine& Source) //constructeur par copie :m_Chaine(NULL) { Chaine(Source.m_Chaine); } CChaine::CChaine(const char* UneChaine) //constructeur spécifique :m_Chaine(NULL) { Chaine(UneChaine); } CChaine::~CChaine() //destructeur { Vider(); } void CChaine::Vider() { if (m_Chaine != NULL) { free(m_Chaine); m_Chaine = NULL; } } bool CChaine::Chaine(const char* UneChaine) { if (UneChaine == NULL) return false; void* Nouveau = realloc(m_Chaine,(strlen(UneChaine)+1)*sizeof(char)); if (Nouveau == NULL) return false; m_Chaine = (char*)Nouveau; strcpy(m_Chaine,UneChaine); return true; } const char* CChaine::Chaine() const { return (m_Chaine != NULL) ? m_Chaine : ""; } bool CChaine::EstNull() const { return (m_Chaine == NULL); } bool CChaine::EstVide() const { return (m_Chaine == NULL) || (m_Chaine[0] == 0); } //////////////////////////// // Classe CChaineComposee // //////////////////////////// CChaineComposee::CChaineComposee() :m_NbrChamps(0),m_Champs(NULL) { } CChaineComposee::CChaineComposee(const CChaineComposee& Source) :CChaine(Source),m_NbrChamps(0),m_Champs(NULL) { if (Source.m_NbrChamps > 0) { m_Champs = (char**)malloc(Source.m_NbrChamps*sizeof(char*)); if (m_Champs != NULL) { m_NbrChamps = Source.m_NbrChamps; for (long n=0; n < Source.m_NbrChamps; n++) { long PosRel = Source.m_Champs[n] - Source.m_Champs[0]; m_Champs[n] = ((char*)Chaine()) + PosRel; } } } } CChaineComposee::CChaineComposee(const char* UneChaine, char UnSeparateur) :CChaine(UneChaine),m_NbrChamps(0),m_Champs(NULL) { Decomposer(UnSeparateur); } CChaineComposee::~CChaineComposee() { if (m_Champs) free(m_Champs); } long CChaineComposee::NombreChamps() const { return m_NbrChamps; } const char* CChaineComposee::Champs(long Indice) const { return ( (Indice >= 0) && (Indice < m_NbrChamps) ) ? m_Champs[Indice] : ""; } bool CChaineComposee::Definir(const char* UneChaine, char UnSeparateur) { if (!Chaine(UneChaine)) return false; return Decomposer(UnSeparateur); } bool CChaineComposee::Decomposer(char UnSeparateur) { m_NbrChamps = 0; char* Texte = (char*)Chaine(); if (Texte == NULL) return false; void* Nouveau = realloc(m_Champs,1*sizeof(char*)); if (Nouveau == NULL) { if (m_Champs) { free(m_Champs); m_Champs = NULL; } return false; } m_Champs = (char**)Nouveau; m_Champs[m_NbrChamps] = Texte; m_NbrChamps++; while (true) { char* Delimiteur = strchr(Texte,UnSeparateur); if (Delimiteur == NULL) return true; *Delimiteur = 0; Texte = Delimiteur + 1; void* Nouveau = realloc(m_Champs,(m_NbrChamps+1)*sizeof(char*)); if (Nouveau == NULL) return false; m_Champs = (char**)Nouveau; m_Champs[m_NbrChamps] = Texte; m_NbrChamps++; } } ////////////////////////////////// // Classe CChargeurFichierTexte // ////////////////////////////////// CChargeurFichierTexte::CChargeurFichierTexte() { } CChargeurFichierTexte::~CChargeurFichierTexte() { } bool CChargeurFichierTexte::Charger(const char* NomFichier, char UnSeparateur, bool (* FctnTraiterLigne)(const CChargeurFichierTexte&, void*), void* Contexte) { const long TailleLigne = 500; char Ligne[TailleLigne+1]; FILE* Fichier; if ( (NomFichier == NULL) || (*NomFichier == 0) ) return false; Fichier = fopen(NomFichier,"rt"); while (fgets(Ligne,TailleLigne,Fichier) != NULL) { long i = strlen(Ligne); if ( (i > 0) && (Ligne[i-1] == '\n') ) Ligne[i-1] = 0; if (Definir(Ligne,'\t')) { if (!FctnTraiterLigne(*this,Contexte)) { fclose(Fichier); return false; } } } fclose(Fichier); return true; }
et le header :
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 #include <BasicConsole.h> #include "vehicule3.h" #include "chaine.h" void main() { CLeTout LeTout; if(LeTout.Charger("Vehicules.txt")) printf("ok"); }
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 #include <BasicConsole.h> #include "chaine.h" class Vehicule3 { public: Vehicule3(); ~Vehicule3(); short NombreDePlace; private: CChaine m_Nom; CChaine m_Immatriculation; }; class CVoiture : public Vehicule3 { public: CVoiture(); ~CVoiture(); private: double m_VTM; //Volume transportable de marchandise }; class CTabVoitures { public: CTabVoitures(); ~CTabVoitures(); private: long m_Nombre; CVoiture** m_Tableau; }; class CLeTout { public: CLeTout(); ~CLeTout(); bool Charger(const char* NomFichier); private: private: static bool FctnTraiterLigne(const CChargeurFichierTexte& CC, void* Contexte); bool TraiterLigne(const CChargeurFichierTexte& CC); private: CTabVoitures m_TV; //Tableau de voitures };
Partager