IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Problème avec vector<char>


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Septembre 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 94
    Points : 41
    Points
    41
    Par défaut Problème avec vector<char>
    Salut,
    J'ai un pb dont je n'ai pas pu résoudre.
    En fait j'utilise un vecteur de caractère pour stocker des variables sous forme de caractères.
    Lors de la compilation j'obtient une chose dont je ne comprends pas.

    main.o: In function `automate::ajouter_noeud(std::vector<noeud*, std::allocator<noeud*> >, int, noeud*)':
    main.cpp.text+0xddb): undefined reference to `automate::chercher_trans(std::vector<noeud*, std::allocator<noeud*> >, std::vector<char, std::allocator<char> >&, int, char)'
    collect2: ld a retourné 1 code d'état d'exécution
    make: *** [liste2] Erreur 1

    Voila ce que j'utilise comme code:
    Declaration:
    void chercher_trans(vector<noeud*> tab,vector<char> tab1,int m,char c);
    Appel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void automate::ajouter_noeud(vector<noeud*> tab,int m,noeud *e)
    {
    	char c;bool trouve=false;
    	vector<char> tab1;
    	noeud *e2=NULL;noeud *e3=NULL;
    	cout<<"choisir le type de noeud à ajouter ""i"" pour input et ""o"" pour output \n";
    	cin>>c;
    	chercher_trans(tab,tab1,m,c); ....
    Utilisation:
    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
    void chercher_trans(vector<noeud*> tab,vector<char> &tab1,int m,char c)
    {
    	noeud *e1=NULL;noeud *e2;
     
    	e1=tab[m-1];
    	if(c=='i')
    	  {
    	     while(e1->suiv1 !=NULL)
    	     {
    		e2=e1->suiv1;
    		e1=e2;
    		tab1.push_back(e1->a);
    	     }
    	   }
    	else if(c=='o')
    	   {
    	      while(e1->suiv1 !=NULL)
    	     {
    		e2=e1->suiv1;
    		e1=e2;
    		tab1.push_back(e1->a);
    	     }
    	   } 	
    }
    Je suis vraiement pressé et ça me bloque dans une étape critique pour moi.
    Merci de m'aider.

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 631
    Points : 30 707
    Points
    30 707
    Par défaut
    Salut,

    Te serait il possible de fournir la définition de ta classe noeud

    D'un autre coté, pourquoi ne pas utiliser, tout simplement une std::string pour maintenir les données que tu as récupérées

    Enfin, je me pose réellement la question de savoir quelle différence il y a entre le fait d'ajouter un élément en entrée ou un élément en sortie...

    J'ai franchement l'impression qu'il y a quelques erreurs de conceptions qui se sont perdues

  3. #3
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    void chercher_trans(vector<noeud*> tab,vector<char> tab1,int m,char c);
    Ici tab1 est passé par valeur alors que plus bas la fonction est définie avec tab1 passé par référence.

  4. #4
    Membre du Club
    Inscrit en
    Septembre 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 94
    Points : 41
    Points
    41
    Par défaut
    Enfin, je me pose réellement la question de savoir quelle différence il y a entre le fait d'ajouter un élément en entrée ou un élément en sortie...
    En fait je suis en train de developper une application de gestion de graphe avec noeuds.
    Et j'ai en fait j'ai besoin de deux types de noeuds:input node et output node(cad chaque noeud peut avoir un certains nombre de noeuds qui résultent d'entrer une transition, et d'autres neuds qui se construisent automatiquement par des transitions de sortie(une sorte de génération de tests de conformance si vous comprener la notion)
    D'un autre coté, pourquoi ne pas utiliser, tout simplement une std::string pour maintenir les données que tu as récupérées
    En fait ce besoin est cree pour eviter le non determinisme dans le graphe:les transitions sont représentés par des caractères. Donc avant d'ajouter un noeud je doit voir si sa transition existe déja dans les transitions sortant du sommet précedant qui devaient etre stockés dans ce vecteur qui me fais ce pb.

    Voila la classe noeud
    class noeud
    {
    public:
    vector<int> tab ; //ensemble des n° des’états destinataires
    char a ; //caractère de la transition conduisant à cet état.
    noeud *suiv1 ; //on utilise une liste chainée.
    noeud *suiv2 ;
    };
    Le vecteur d'entier doit contenir les numéros des noeuds qui se créent depuis la même transition.

    Ici tab1 est passé par valeur alors que plus bas la fonction est définie avec tab1 passé par référence.
    Il me parait que c ça mon pb.
    Est ce que tu peux me proposer une solution parce que je ne voix pas comment corriger ça.
    Merci beaucoup.

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 631
    Points : 30 707
    Points
    30 707
    Par défaut
    Mais, dans le sens où le code qui se trouve dans la partie if(c=='i') est strictement identique à celle qui se trouve dans la partie else if(c=='o') il me semble qu'il y a clairement moyen d'améliorer les choses...

    D'abord, tu fais deux fois la même chose , or faire deux fois la même chose, c'est... la faire une fois de trop...

    Pourquoi ne pas modifier le code sous une forme proche (aucune autre correction) de
    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
     
    void chercher_trans(vector<noeud*> tab,vector<char> &tab1,int m,char c) 
    {  
        noeud *e1=NULL;
        noeud *e2; 
        e1=tab[m-1];
        while(e1->suiv1 !=NULL)  
        {  
            e2=e1->suiv1; 
            e1=e2; 
            if(c=='i')
                tab1.push_back(e1->a);
            else if(c=='o')  
                tab1.push_back(e1->a);
        }
     
    }

    et, en plus, tu rend une fonction responsable de savoir s'il s'agit d'un input ou d'un output, et l'autre responsable de gérer le "basard"...


    Ne crois tu pas qu'il serait clairement opportun de réfléchir à un moyen qui permette à une seule fonction de gérer ces deux choses si étroitement liées

    Cela nous donnerait la fonction sous une forme proche de
    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
    /* plus besoin de passer le caractère, la fonction
     * se charge de le demander à l'utilisateur
     */
    void chercher_trans(vector<noeud*> tab,vector<char> &tab1,int m) 
    {  
        char c;
        cout<<"choisir le type de noeud à ajouter \"i\" pour input et "
            <<"\"o\" pour output"<<endl;
        cin>>c;
        noeud *e1=NULL;
        noeud *e2; 
        e1=tab[m-1];
        while(e1->suiv1 !=NULL)  
        {  
            e2=e1->suiv1; 
            e1=e2; 
            if(c=='i')
                tab1.push_back(e1->a);
            else if(c=='o')  
                tab1.push_back(e1->a);
        }
    }
    En outre, le nom chercher_trans ne me paraît vraiment pas opportun non plus:

    Le nom *semble* indiquer que la fonction s'occupe de la recherche d'un élément, mais le code nous montre que la fonction... ajoute un élément

    Le problème, c'est que dans la vie de tous les jours, cela revient à inverser la signification des mots "accélérer" et "ralentir"...

    Si un jour je te dis "accelère, la police est derrière nous" cela risque de poser problème, non

    A titre personnel, le nom de cette fonction serait bien mieux en ajouter_trans...

    Enfin, la logique même que tu applique dans ces deux tests me paraît des plus... suspectes telle que tu la présente...

    Si j'ai bien compris, ta structure noeud se présente sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct noeud
    {
        noeud* suiv1;
        char a;
        /*les autres informations */
    };
    Et, la logique que tu fournis pour l'instant, c'est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    while(e1->suiv1 !=NULL) /*tant qu'il y a un élément suivant */
    {
        e2=e1->suiv1; /* e2 reçoit l'élément qui suit e1 */
        e1=e2; /* e1 reçois la valeur de e2 */
        /* au passage, un code du genre de
         *  e1=e1->suiv1; 
         * aurait fait exactement pareil */
            tab1.push_back(e1->a);/* on ajoute la valeur du caractère a de e1
                                   * au tableau
                                        */    
    }
    C'est peut être ce que tu veux faire, mais... il faut savoir que, dans ce cas, tu recopie l'intégralité des valeurs... Est-ce ce que tu veux

    Enfin, je voudrais que tu précise la différence "physique" entre un noeud qui serait "input" et un autre qui serait "output"...

    Au mieux, c'est exactement le même type de noeud, cela n'a en aucun cas avoir avec la donnée que tu veux placer dans le vecteur de caractères, et tu fournis simplement un membre "sens" à ton noeud (0=in 1=out ou inversement, selon ton humeur du moment), au pire, ce sont des données réellement spécifiques qui héritent de ton type noeud sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    struct Noeud
    {
        /*...*/
    };
    struct NoeudInput:public Noeud
    {
        /* ce qui est particulier au noeud d'entrée */
    };
    struct NoeudOutput: public Noeud
    {
        /* ce qui est particulier au noeud de sortie */
    };
    Les deux solutions peuvent trouver de la place dans un std::vector<Noeud*> (si tant est qu'il soit nécessaire de les mettre ensemble), et, de toutes manières, cela n'influe en rien le travail de la fonction...

  6. #6
    Membre du Club
    Inscrit en
    Septembre 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 94
    Points : 41
    Points
    41
    Par défaut
    Merci de ta réponse.
    Alors je pense que je doit te raconter ce que je suis en train de faire pour te mettre dans mon plateau.
    D'abord je doit te préciser que mon codeest en cours de construction et on m'a demandé des fonctionnalités bien determinés donc j'ai besion de faire des choses qui marchent,pour le moment car il faut en deuxième étapes de suivre ce que j'ai fait et de l'améliorer comme t'as proposé.
    Donc mon travail est faire une application qui me permet de représenter un graphe sous forme de noeuds avec des transitions.
    Aprés ceci je doit implémenter un algorithme de génération de tests afin de tester la conformance de ces tests avec le graphe de spécification.
    Au début j'ai choisi une classe noeud de ce type:
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class noeud{
    int n;//pour le n° du nœud
    char a; //pour la transition amenant à cet état
    noeud *suiv1 ; //on utilise une liste chainée.
    };
    Ce que j'ai choisi comme structure de donné c les listes d'adjacence pour ce que j'ai lu dans ce lien
    http://rperrot.developpez.com/articl...?page=sommaire
    Donc j'ai fais une classe graphe de ce type:
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class graphe{
    int n;// nbre d'état
    vector<noeud*> tab;//vecteur pointant sur les listes des successeurs.
    En avançant dans le projet, d'autre besoins sont crées.
    Le premier pour lequel je vais expliquer les input node et les output node
    En fait lors de la généation des test parfois on se trouve devant un noeud qui doit avoir une transition en entrée(input node) pour evoluer et pour tester la conformance avec le graphe de spécification on doit voir si l'état obtenu existe dans l'ens d'état atteint dans la spec par cette transition(on doit donc parcourir une liste pour chercher ces états).
    C pourquoi j'ai choisi de faire deux listes pour chaque type de noeud pour minimiser le temps de recherche puisqu'on sais dés le début le type du noeud qu'on cherche les succ.
    De même un output node est un noeud qui lorsqu'il est atteind evolue automatiquement par des transitons bien définis donc aussi on doit lors du test on doit vérifier la conformance avec ce qu'il existe dans la spec.
    Deuxièment, un autre besoin est crée.C que lorsque on a un état de non déterminisme je doit en tenir en compte pour une représenttion plus économique.
    Plus précisement, lorsque on évolue depuis un noeud à deux états différents par la même transition on doit me pas ajouter deux noeud mais un seul qui contient l'information des deux noeuds(noramlement le numéro des deux noeuds).
    C pourqoui j'ai de choisi de modifier la classe noeud pour supporter ceci.
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class noeud{
    vector<int> tab;//vecteur des numéros des noeuds qui ont "a " comme transition.
    char a;
    noeud *suiv1;
    noeud *suiv2;
    };
    Voile ce que je peux te dire et j'éspère que c clair maintenant.
    En outre, le nom chercher_trans ne me paraît vraiment pas opportun non plus:
    En fait ce qu'ai choisi de faire avant d'ajouter un noeud je doit vérifier que sa transition existe ou pas donc je fais une petite recherche des transitions possibles de cet état et puis voir si la transition du nouveau noeud existe ou non dans cet ensemble.


    Voila j'ai parlé beaucoup et j'espère que j'ai bien exposé la chose parce que j'ai qq pbs dans l'implémentation/.



    balises [code] rajoutées par r0d. Merci d'y penser dorénavant.

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 631
    Points : 30 707
    Points
    30 707
    Par défaut
    Il me semble réellement que, si tu travailles en équipe (ce que laisse supposer ton message) l'équipe travaille un peu au "petit bonheur la chance", et que tu le fait toi aussi...

    Le fait de se "ruer sur le clavier" et de "commencer à vomir des lignes et des lignes de code" sans savoir ce qui devra précisément être codé est... le meilleur moyen de foncer dans le mur.

    Que ce soit pour le projet complet ou pour une partie bien précise du projet, il faut toujours suivre la même ligne de conduite.

    Avant même de commencer à écrire la première ligne de code, il faut savoir précisément d'où on part, où l'on veut arriver, comment y arriver, ce qui nous sera nécessaire pour y arriver et ce que tout cela implique.

    Il est très important, d'autant plus si c'est dans une optique de travail collaboratif, d'avoir une idée très précise des éléments qui interviennent et de la manière dont ces éléments vont "discuter" entre eux...

    Sinon, le type qui va gérer le son va n'en faire qu'à sa tête dans la partie qui permet de faire communiquer le son avec le jeu, le type qui gère l'affichage pareil avec la partie qui s'occupe de la "création du monde", et, au final, quand bien même toutes les parties seraient nickel chrome, elles ne pourraient pas travailler en commun... parce qu'elles ne savent pas communiquer entre elles.

    Avant de pouvoir travailler sur un "Noeud", il faut savoir précisément ce que l'on attend de ce "Noeud".

    Si ce "Noeud" est destiné à être regroupé avec d'autres "Noeuds" au sein d'un graphe, il faut savoir ce que l'on attend du "Graphe", et si plusieurs "Graphe" doivent communiquer entre eux, il faut savoir la manière dont ils vont devoir communiquer entre eux.

    Si un "Graphe" ou un "Noeud" doit interagir avec autre chose que des "Noeud" ("Objet fixe","Objet mobile", "Vivant (joueur, pnj, monstre, "détail")") il faut savoir "dés le départ" les interactions qui vont se produire, quand, et comment...

    Une fois que tu a cela, tu peux commencer à concevoir ta partie "Graphe" et ta partie "Noeud", en connaissance de cause.

    Et là encore, avant d'écrire du code "en espérant que cela fonctionne", il y a fortement intérêt, pour chaque "interaction" à se poser la question de savoir
    comment cela va interagir
    et plus précisément
    quelle est la logique qui devra être suivie pour que telle interaction fonctionne correctement dans "la plus grande majorité de cas possible" (le 100% n'existant pas)
    Je suis tout à fait d'accord qu'il est impossible d'avoir dés le départ toutes les réponses à toutes les questions, mais le but est quand même d'avoir un maximum de réponses avant de commencer.

    Toutes les questions que tu te sera posées avant d'écrire ta première ligne de code seront des solutions aux problèmes qui ne manqueraient pas de te faire partir dans toutes les directions lorsque vient le moment de l'implémentation, avec parfois des incompatibilités majeures.

    En plus, il me semble intéressant de te rappeler que le C++ est un langage à vocation "orientée objet"...

    Il me semblerait honnêtement intéressant pour toi de travailler en orienté objet et non en "séquentiel" comme tu semble le faire pour l'instant.

    Ton travail permettra bien plus les "modifications tardives"

    En outre, la bibliothèque standard fournit une quantité impressionnante de classes dont il te serait sans doute profitable d'abuser.

    Enfin, il faut aussi savoir que le mieux, c'est encore de coder les tests avant même de coder les fonctionnalités que tu prévois de donner.

    La raison en est simple: lorsque tu créera tes tests, cela te permettra peut-être de trouver des incohérences dans ce que tu a conçu, voire, de découvrir certains besoins qui n'étaient pas apparu à la conception...

    Mettons nous bien d'accord: il ne s'agit pas ici de tirer à boulet rouge sur ton travail ou sur ton "investissement"... Il s'agit *surtout* de te faire prendre conscience que, même si tu es très motivé, ta manière de travailler va finir par te poser problèmes

    PS pense à la balise "code" quand tu présente du code, même si ce ne doit être que quelque lignes

Discussions similaires

  1. Problème avec vector de classe template :(
    Par coyotte507 dans le forum Langage
    Réponses: 7
    Dernier message: 16/04/2008, 13h40
  2. Réponses: 2
    Dernier message: 07/12/2007, 03h19
  3. Problème avec Vector et Iterator
    Par boudincweole10 dans le forum Langage
    Réponses: 1
    Dernier message: 08/04/2007, 08h26
  4. [Migration BDE en ADO][SQLServer] Problème avec les types char
    Par pitango dans le forum Bases de données
    Réponses: 3
    Dernier message: 15/03/2007, 18h17
  5. Problème avec vector par référence
    Par vdumont dans le forum SL & STL
    Réponses: 11
    Dernier message: 09/05/2006, 09h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo