I've been trying to overcome the "LNK1561 entry point must be defined" error and finally achieve it by changing the System field in the Linker options inside the project parameters to Console. Now, I have a LNK2019 and I'm not finding any solution. I've done a bunch of other C++ projects with headers and a .cpp with a main inside and they were working quite well. I don't understand why this time it doesn't want to generate the solution into a .exe. The code is compiling well but I've been using a bunch of new stuff so maybe that's where I'm wrong.
Here's the first Header:
#ifndef TP2_H
#define TP2_H
#pragma once
# include <string>
# include <iostream>
using namespace std;
class Personne
{
private:
string nom;
string prenom;
int age;
string metier;
public:
Personne();
Personne(string leNom, string lePrenom, int lAge, string leMetier);
~Personne();
friend istream& operator>> (istream& in, Personne& n);
friend ostream& operator<< (ostream& out, Personne& n);
};
#endif
The second header:
#ifndef ARBRES_H
#define ARBRES_H
#pragma once
#include <iostream>
#include <vector>
using namespace std;
// noeud pour un arbre binaire contenant des informations de type T
template <class T>
class Noeud
{
private:
T* element; // élément du noeud
Noeud<T> *parent; // Pointeur vers le parent
Noeud<T> *gauche; // Pointeur vers le fils gauche
Noeud<T> *droit; // Pointeur vers le fils droit
public:
//constructeur du noeud
Noeud(T *elem = NULL)
{
element = elem;
parent = NULL;
gauche = NULL;
droit = NULL;
}
// destructeur du noeud
~Noeud ()
{
}
// retourne l'enfant où "i" represente la position de l'enfant (droit ou gauche)
Noeud<T> * Enfant(int i) const
{
if (i == 0)
return gauche;
if (i == 1)
return droit;
}
// retourne le parent du noeud
Noeud<T> *Parent () const
{
return parent;
}
// retourne un pointeur vers l'élément du noeud (les infos)
T *Element() const
{
return element;
}
// modifie la valeur de l'élément
void RemplacerElement( T *ele )
{
element = ele;
}
//retourne vrai si le noeud est une feuille
bool EstUneFeuille () const
{
return (gauche == NULL) && (droit == NULL);
}
//retourne vrai si le noeud est une racine
bool EstUneRacine () const
{
return (parent == NULL);
}
// détache l'enfant du noeud et retourne un pointeur vers ce noeud
Noeud<T> *Detacher (Noeud<T>* Enfant)
{
Noeud<T> *temp;
if (gauche == Enfant) {
temp = gauche;
gauche = NULL;
} else if (droite == Enfant) {
temp = droite;
droite = NULL;
} else
return NULL;
return temp;
}
// attache l'enfant au noeud. Retourne vrai si l'opération est réussie
bool Attacher(Noeud<T>* nouvelEnfant)
{
if (gauche == NULL)
gauche = nouvelEnfant;
else
droite = nouvelEnfant;
return 0;
}
// le mot clé "friend" indique que la fonction peut utiliser les membres privés de la classe Noeud
template<class U>
friend istream& operator>> (istream& in, Noeud<U>& n);
template<class U>
friend ostream& operator<< (ostream& out, Noeud<U>& n);
};
// surcharge de l'opérateur >> pour un noeud
template <class T>
istream& operator>> (istream& in, Noeud<T>& n)
{
in >> n.element >> n.parent >> n.gauche >> n.droit
return in;
}
// surcharge de l'opérateur << pour un noeud
template <class T>
ostream& operator<< (ostream& out, Noeud<T>& n)
{
// À compléter
return out;
}
// Patron de classe définissant la classe "Arbres"
// contenant des informations de type T
template <class T>
class Arbres
{
// Patron de classe définissant la classe "Arbres"
private:
vector<Noeud<T>*> racines;
Noeud<T>* noeudCourant;
public:
//constructeur d'une classe Arbres
Arbres()
{
noeudCourant = NULL;
}
// destructeur d'une classe Arbres
~Arbres ()
{
}
// ajoute un arbre de niveau 0 (un noeud) à la liste des racines
int NouveauNoeud(Noeud<T>* n)
{
racines.push_back(n);
}
// positionne le noeud courant sur le noeud racine d'indice i
void SetCourant(int i)
{
noeudCourant = &racines.at(i);
}
// Déplace le noeud courant vers son enfant i
void NaviguerVersEnfant(int i)
{
noeudCourant = noeudCourant.Enfant(i);
}
// Déplace le noeud courant vers son parent
void NaviguerVersParent()
{
noeudCourant = noeudCourant.Parent();
}
// mets le noeud en position i de la liste racine comme enfant du noeud courant
void joindreCourant(int i)
{
Noeud<T>* temp = noeudCourant;
if (noeudCourant.gauche == NULL) {
SetCourant(i);
temp.gauche = noeudCourant;
}
else if(noeudCourant.droit == NULL) {
SetCourant(i);
temp.droit = noeudCourant;
}
}
// Détache le noeud courant de son parent
void DetacherCourant()
{
if (noeudCourant.parent.gauche == noeudCourant) {
noeudCourant.parent.gauche = NULL;
}
else
noeudCourant.parent.droit = NULL;
}
// supprime le noeud courant
void SupprimerCourant()
{
delete noeudCourant.element;
// enfants?
// enfants des enfants?
delete noeudCourant;
}
// retourne la liste des noeuds racines
const vector<Noeud<T>*>* getRacine() const
{
return racines;
}
// retourne le noeud courant
const Noeud<T>* getCourant() const
{
return noeudCourant;
}
// le mot clé "friend" indique que la fonction peut utiliser les membres privés d'une classe Arbres
template<class U>
friend istream& operator>> (istream& in, Arbres<U>& n);
template<class U>
friend ostream& operator<< (ostream& out, Arbres<U>& n);
};
// surcharge de l'opérateur >> pour un objet de type Arbres<T>
template <class T>
istream& operator>> (istream& in, Arbres<T>& n)
{
// À compléter
return in;
}
// surcharge de l'opérateur << pour un objet de type Arbres<T>
template <class T>
ostream& operator<< (ostream& out, Arbres<T>& n)
{
// À compléter
return out;
}
#endif
And here's the source code containing my main:
#include "TP2.h"
#include "Arbres.h"
#include <fstream>
#include <algorithm>
using namespace std;
Personne::Personne() {
return;
}
Personne::Personne(string leNom, string lePrenom, int lAge, string leMetier)
{
nom = leNom;
prenom = lePrenom;
age = lAge;
metier = leMetier;
return;
}
Personne::~Personne()
{
// À compléter
return;
}
istream& operator>> (istream& in, Personne& n)
{
in >> n.nom >> n.prenom >> n.age >> n.metier;
return in;
}
ostream& operator<< (ostream& out, Personne& n)
{
out << n.nom << n.prenom << n.age << n.metier;
return out;
}
template <class Personne>
void main(){
ifstream Transaction;
ifstream Data_input;
ofstream Data_ouput;
string transaction_fichier;
string arbres_fichier;
cout << "\nEntrer le nom du fichier transaction: " << endl;
cin >> transaction_fichier;
cout << "Entrer le nom du fichier arbres: " << endl;
cin >> arbres_fichier;
Transaction.open(transaction_fichier);
if (Transaction.fail())
cout << "\nError 404 : File not found";
while (!Transaction.eof()) {
char op[1], FILENAME[50]; // Operateur, Nom d'un fichier
int i, lAge; // Indice, Age
Personne *personne; // Pointeur d'une personne
Noeud<Personne> *noeud; // Pointeur d'un noeud
string leNom, lePrenom, leMetier, buffer; // Nom, Prenom, Metier, buffer
Arbres<Personne>* structure = nullptr;
structure = new Arbres<Personne>;
Transaction >> op;
switch (op[0]) {
case '*':
structure.noeudCourant = new Noeud<Personne>();
structure.noeudCourant.element = new Personne();
Data_input >> structure.noeudCourant.element;
structure.NouveauNoeud(structure.noeudCourant);
break;
case '&':
Transaction >> i;
structure.noeudCourant = structure.racines[x];
break;
case '>':
Transaction >> i;
structure.noeudCourant = structure.noeudCourant.Enfant(i);
break;
case '<':
Transaction >> i;
structure.noeudCourant = structure.noeudCourant.Parent();
break;
case '+':
Transaction >> i;
if (noeudCourant.gauche == NULL) {
noeudCourant.gauche = structure.racines[i];
}
else if (noeudCourant.droit == NULL) {
noeudCourant.droit = structure.racines[i];
}
else {
cout << "/nERROR: Aucun Enfant disponible sur le noeud Courant " << endl;
break;
}
break;
case '-':
structure.noeudCourant.Parent().Detacher(structure.noeudCourant);
break;
case '!':
delete structure.noeudCourant;
break;
case '%':
for (int x = 0; x < structure.racines.size(); x++) {
cout >> structure.racines[x].Element();
}
break;
case '?':
cout >> structure.noeudCourant.Element();
break;
case '#':
if (structure == nullptr) {
// Supprime la structure actuel
}
else {
Transaction >> FILENAME;
Data_input.open(FILENAME);
while (!Data_input.eof()) {
Data_input >> buffer;
int n = count(buffer.begin(), buffer.end(), '-');
if (n == 0) {
structure.noeudCourant = new Noeud<Personne>();
structure.noeudCourant.element = new Personne();
Data_input >> structure.noeudCourant.element;
structure.NouveauNoeud(structure.noeudCourant);
}
else {
CreerNouveauNoeud(structure.noeudCourant, (n / 2)); // boucle recursive creant un nouveau noeud a lendroit ou il doit etre placer
}
}
}
break;
case '$':
Transaction >> FILENAME;
Data_ouput.open(FILENAME);
// Lecture de l'arbre de la meme facon qu'on l'ecrit
// imprimer le contenue de la structure personne a chaque boucle changeant le noeudCourant
break;
default:
cout << "\nError420 Operator not supported: " << op << endl;
break;
}
}
// Fin du programme
return;
}
template <class Personne>
void CreerNouveauNoeud(Noeud<Personne>* noeudCourant, int val) {
if (val == 1) {
if (noeudCourant.gauche == NULL) {
noeudCourant.gauche = new Noeud<Personne>();
noeudCourant = noeudCourant.gauche;
noeudCourant.element = new Personne();
Data_input >> Arbres.noeudCourant.element;
}else if (noeudCourant.droit == NULL) {
noeudCourant.droit = new Noeud<Personne>();
noeudCourant = noeudCourant.droit;
noeudCourant.element = new Personne();
Data_input >> Arbres.noeudCourant.element;
}
else {
cout << "\nERROR: Structure dans le fichier texte incorrect (limite de 2 sous-noeuds par noeud)" << endl;
return;
}
}
else {
if (noeudCourant.droit == NULL)
CreerNouveauNoeud(noeudCourant.gauche, val - 1);
else
CreerNouveauNoeud(noeudCourant.droite, val - 1);
}
return;
}
Note that this is not the final version, I still need to add a bunch of stuff to delete/destroy some of the things I created from this program. I was willing to test only the cases < > + in my switch.
Any idea where's the problem? Thanks :)