0

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 :)

  • Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Ken White Mar 25 '16 at 18:17
  • Doy you know what the "entry point" is? It's the `main` function all C++ program needs to have. It's *not* a template. By the way, the C++ specification says that `main` should always return an `int`. – Some programmer dude Mar 25 '16 at 18:21
  • Is this *really* the smallest example you cannot compile successfully? Please see what a ["Minimal, Complete, Verifiable Example"](http://stackoverflow.com/help/mcve) is (also: ["Short, Self-Contained, Correct/Compilable Example"](http://sscce.org/)). For instance: if your problem is not with `case '?': cout >> structure.noeudCourant.Element();` then it shouldn't appear in your question text... – HostileFork says dont trust SE Mar 25 '16 at 18:24
  • Ok, I changed the void main for a int main and I completly erase template before the main. Now I'm having a stange error on everywhere i'm using my pointer structure which is poiting on a Arbres structure taking a type Personne aka this line : Arbres* structure – Alexandre Blanchet Mar 25 '16 at 18:42
  • Thanks Joachim Pileborg I think the templates like for the main was the problem, I didn't know we can't do that! – Alexandre Blanchet Mar 25 '16 at 18:48

0 Answers0