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 :

Commande Sort C++


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Commande Sort C++
    Bonjour,
    Voila je suis étudiant en première année de DUT, et dans le cadre de mes révisions j'essaie de créer les commandes Unix en C++.
    Or me voici face a un problème que je ne peux résoudre seul.
    C'est pourquoi je demande votre aide, pour la réalisation de la commande Sort.
    Tout d'abord, il y a une erreur au niveau de la ligne 39 que je n'arrive pas a résoudre.
    Et par la même occasion, Comment faire pour que le programme utilise l'entrée standard, pour affecter les variables, qui au préalable doivent être au nombre désiré par l'utilisateur.



    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
     
    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
    ////////////////////////////////////////////////////////////////
    class phrase
       {
       private:
          string texte;
          public:
    //--------------------------------------------------------------
    //--------------------------------------------------------------
       void displayphrase()
          {
          cout << texte;
          }
    //--------------------------------------------------------------
       string getLast()  
          { return texte; }
       }; //end class phrase
    ////////////////////////////////////////////////////////////////
    class ArrayInOb                 // L'erreur survient ici !!
       {
       private:
          vector<phrase*> v;        
          int nElems;                
       public:
    //--------------------------------------------------------------
       ArrayInOb(int max) : nElems(0)  
          {
          v.resize(max);              
          }
    //--------------------------------------------------------------
     
       void insert(string txt)
          {
          string texte;
          v[nElems] = new phrase(texte);
          nElems++;       
          }
    //--------------------------------------------------------------
       void display()              
          {
          for(int j=0; j<nElems; j++)    
             v[j]->displayphrase();     
     
          }
    //--------------------------------------------------------------
       void insertionSort()
          {
          int in, out;
          for(out=1; out<nElems; out++)
             {
             phrase* temp = v[out];     
             in = out;                 
     
             while( in>0 && v[in-1]->getLast() > temp->getLast() )
                {
                v[in] = v[in-1];      
                --in;                  
                }
             v[in] = temp;            
             } //end for
          } //end insertionSort()
    //--------------------------------------------------------------
       }; //end class ArrayInOb
    ////////////////////////////////////////////////////////////////
    int main()
          {
          int i,j;
          int maxSize = 100;  
          ArrayInOb arr(maxSize);   
     
         //create array
     
     
          arr.insert("John");
          arr.insert("Smith");
          arr.insert("Edward");
          arr.insert("Yee");
     
          cout << "Before sorting:" << endl;
          arr.display();               
          arr.insertionSort();     
          cout << "After sorting:" << endl;
          arr.display();           
          return 0;
    }

    Merci de votre aide

  2. #2
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    Salut MicroOnde !
    Pour commencer, indente ton code J'ai les yeux qui piquent !
    Ensuite pourrais-tu copier/coller l'erreur que te signale ton compilateur ?

    Pour l'utilisation de l'entrée standard, je comprend pas trop... Tu veux que l'utilisateur rentre lui-même la valeur des variables ?

    P.S : Il me semble d'ailleurs que l'entrée standard est le clavier.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Salut, et bienvenue sur le forum (à tous les deux )
    Citation Envoyé par hijackMe Voir le message
    Salut MicroOnde !
    Pour commencer, indente ton code J'ai les yeux qui piquent !
    Il s'était simplement trompé de bouton:

    Il y a le bouton qui place une balice CODE (c'est le #) et, juste à coté, il y a le bouton "citation" (QUOTE) qui a la forme d'un phylactère...

    Cela ne vaut pas la peine de l'engueuler ainsi (d'autant plus que les modérateurs veillent au grain)

    Bon, je vais maintenant essayer de voir les différents problèmes
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Salut, et bienvenue sur le forum (à tous les deux )
    Il s'était simplement trompé de bouton:

    Il y a le bouton qui place une balice CODE (c'est le #) et, juste à coté, il y a le bouton "citation" (QUOTE) qui a la forme d'un phylactère...

    Cela ne vaut pas la peine de l'engueuler ainsi (d'autant plus que les modérateurs veillent au grain)
    Oups autant pour moi !
    Mais je ne l'ai pas engueulé, c'était juste un conseil au cas où il ne le ferait pas (j'en ai quelques exemples dans ma classe )

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 176
    Points
    1 176
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
       void insert(string txt)
          {
          string texte;
          v[nElems] = new phrase(texte);
          nElems++;       
          }
    déjà ça ça va pas faire grand chose

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Cet interlude sur les différentes balises dont on dispose étant fini, je me pose quand même quelque questions peut être idiotes, mais...

    Pourquoi vouloir gérer des pointeurs de type phrases dans ta classe ArrayInOb au lieu de, tout simplement, utiliser... des instances de phrases

    En effet, telle qu'elle est présentée, ta classe ArrayInOb pose un grave problème de... fuite mémoire: Tu alloue dynamiquement de la mémoire pour chaque élément que tu souhaite y ajouter, mais, cette mémoire n'est jamais libérée...

    Je sais bien que les systèmes actuels proposent de plus en plus de mémoire, mais il ne faut pas oublier que, très souvent, ton application ne sera pas la seule à fonctionner sur l'ordinateur ... Il reste donc malgré tout très important d'éviter d'en gaspiller, car, tôt ou tard, ton application finira par fait planter le système de manière irrémédiable

    La solution serait donc, au minimum, de définir le destructeur de ta classe ArrayInOb, sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ArrayInOb ::~ArrayInOb()
    {
        for(vector<phrase*>::iterator it=v.begin(); it!=v.end();++it)
            delete (*it);
    }
    mais cela ne résoudrait qu'à moitié le problème, car, telle qu'elle est là, ta classe ArrayInOb est... assignable et copiable, avec comme résultat qu'il est donc possible que deux instances différentes de ArrayInOb partagent certains pointeurs.

    Si, par exemple, tu crées une copie de l'instance ("d'origine") de ta classe ArrayInOb, tu te trouvera dans une m...de noire lorsque la copie (ou l'instance d'origine) sera détruite: les pointeurs contenus dans l'instance "survivante" pointeront vers... une adresse déjà libérée.

    Les problèmes que peut engendrer cette situation sont multiples:
    1. Toute tentative d'accès à un des éléments de l'instance survivante enverra le processeur "cueillir des pâquerettes" (qui réagira sans doute en lançant une erreur de segmentation).
    2. Lorsque l'instance survivante sera à son tour détruite, il y aura ce que l'on appelle une "double tentative de libération de la mémoire" (ben oui, l'adresse pointées par les différents éléments a déjà été libérée lorsque la première instance a été détruite )
    Il n'est pas impossible de résoudre ces problèmes, à condition de redéfinir également le constructeur par copie et l'opérateur d'affectation (ou de choisir la solution inverse qui consiste à interdire la copie et l'affectation), mais c'est, finalement, se faire du mal pour rien

    En effet, une bonne pratique à garder à l'esprit consiste à n'utiliser les pointeurs que... quand on n'a pas d'autre choix, par exemple, parce que l'on veut gérer une collection d'objets polymorphes, en les faisant passer pour leur "type de base".

    Dans le cas présent, la classe phrase n'est absolument pas polymorphe, et tu n'as donc aucun besoin de la gérer comme telle (de lui donner une "sémantique d'entiter").

    Par contre, il serait sans doute intéressant de donner un constructeur prenant... une (référence constante sur) std::string à ta classe phrase.

    En effet, il existe un principe nommé RAII qui conseille de faire en sorte qu'une instance de classe soit directement initialisée correctement...

    Et c'est d'autant plus vrai que, autrement, tu ne dispose d'aucun moyen de... définir la valeur de texte

    Au passage, il y a un principe qui s'appelle "const correctness" qui conseille de déclarer constant tout ce qui ne doit pas être modifié.

    Par exemple, il est intéressant de déclarer les fonctions membres d'une classe qui ne modifient pas l'objet au départ duquel elles sont invoquées comme fonctions constantes.

    En effet, il est tout à fait possible d'appeler une fonction constante depuis un objet qui ne l'est pas, mais il est par contre interdit d'appeler une fonction non constante depuis un objet qui l'est.

    Au final, ta classe phrase pourrait ressembler à quelque chose comme:
    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
    class phrase
    {
        public:
            /* le constructeur */
            phrase(std::string const & t):texte(t){}
            /* ces deux fonctions ne modifient pas l'objet et peuvent donc
             * être appelées depuis des objets constants :D
             */
            void displayphrase() const 
           {
                cout << texte;
           }
           /* je m'interroge sur le nom de cette fonction...
            * Si on traduit, elle signifie "prendre le dernier", mais le dernier quoi???
            * il n'y a qu'une chaine, comment pourrait il y en avoir
            * ... une dernière??
            */
           std::string const & getLast() const { return texte; }
        private:
            std::string texte;
    }
    Ce n'est d'ailleurs qu'un détail, mais plutôt que de définir une fonction displayphrase, pourquoi ne pas redéfinir... l'opérateur << de manipulation de flux

    Cela pourrait prendre la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    std::ostream & operator << (ostream & ofs, phrase const & p)
    {
        ofs<<p.getLast();
        return ofs;
    }
    Et je reviens maintenant sur la fameuse classe ArrayInOb, car, jusqu'à présent, je n'ai fait que parler de manière générale à son sujet...

    Il faut par exemple savoir que la classe std::vector (comme toutes les collections fournies par la STL d'ailleurs) dispose... d'une fonction membre size() qui permet... de connaitre le nombre d'élément qu'elles contiennent.

    Cela implique que, au minimum, ta logique est inversée par rapport à ce que tu souhaites faire, et qu'elle est même fausse si on y regarde d'un peu plus près

    En effet, si j'ai bien compris, tu veux limiter le nombre de phrases qu'une instance de ArrayInOb peut avoir.

    J'ai déjà du mal à comprendre pour quoi, mais, nous dirons que cela fait encore partie des choses que je peux accepter

    Par contre, ce qui me chagrine, c'est que tu ne vérifie absolument pas, dans la fonction insert, que tu n'aies pas dépassé cette valeur.

    Autrement dit, si tu n'es pas assez attentif, il arrivera fatalement un moment où... tu arrivera à "taper" en dehors des éléments prévus pour ton vecteur, et ca, ca occasionnera, au mieux, des résultats inconsistants

    De plus, il faut savoir que la classe vector (comme toutes les collections fournies par la STL, d'ailleurs) dispose d'une fonction qui ... permet de savoir combien d'éléments sont dans la collection: la fonction size().

    On peut donc se dire que ta logique est, au minimum, inversée par rapport à ce qu'il faudrait faire:

    Il ne faut pas redimensionner le vector au départ et compter "par ailleurs" le nombre d'éléments que tu y a mis, mais bel et bien... garder quelque part le nombre à ne pas dépasser, et se baser sur la taille du vector pour voir si on peut encore ajouter un élément (si tant est qu'il soit effectivement opportun de limiter le nombre d'éléments, ce sur quoi je répète avoir un gros doute ).

    Au final, ta classe ArrayInOb devrait plutôt ressembler,
    pour la version sans limitation de phrase à:
    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
    class ArrayInOb
    {
        public:
            ArrayInOb(){}
            void insert(std::string const & s)
            {
                /* je profite du constructeur que j'ai rajouté :D */
                v.push_back(phrase(s));
            }
            void display()              
            {
                /* il y a d'autres possibilités, basées sur les itérateurs et
                 * même (avec la nouvelle norme en cours de finalisation)
                 * quelques trucs très sympa :D
                 */
                for(int j=0; j<v.size(); j++)    
                     v[j]->displayphrase();     
             }
        private:
            std::vector<phrase> v;
    };
    et, pour sa version avec une limitation:
    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
    class ArrayInOb
    {
        public:
            /* il vaut mieux utiliser size_t car le nombre d'élément sera d'office...
             * positif :D
             */
            ArrayInOb(size_t m):m(m){}
            void insert(std::string const & s)
            {
                /* je profite du constructeur que j'ai rajouté :D */
                if(v.size()<m)
                    v.push_back(phrase(s));
            }
            void display()
            {
                /* il y a d'autres possibilités, basées sur les itérateurs et
                 * même (avec la nouvelle norme en cours de finalisation)
                 * quelques trucs très sympa :D
                 */
                for(size_t j=0; j<v.size(); j++)
                     v[j].displayphrase();
             }
        private:
            std::vector<phrase> v;
            size_t m;
    };
    ET pour terminer ce "roman", je voudrais enfin m'attaquer à... ta fonction insertionSort...

    Je ne suis vraiment pas sur que l'insertion sort soit... le meilleur moyen de trier ta collection...

    Il existe en effet des algorithmes tout prêt qui ne demandent qu'à servir (dans le fichier d'en-tête fourni par le standard sous le nom de... algorithm ), dont un algorithme nommé... sort.

    Tout ce qu'il lui faut, c'est le moyen de déterminer si un objet est strictement plus petit qu'un autre.

    Le plus facile pour y arriver consiste, simplement, à définir l'opérateur plus petit que "<" pour le type manipulé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bool operator<(phrase const & p1, phrase const & p2)
    {
        return p1.getLast()<p2.getLast();
    }
    et nous pourrions donc avoir une fonction (membre de ArrayInOb) proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void ArrayInOb::sort()
    {
        std::sort(v.begin(),v.end());
    }
    Nous pourrions aussi nous baser sur ce que l'on appelle un foncteur, ce qui nous donnerait un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct comPhrase
    {
        bool oprator()(phrase const & p1, phrase const & p2)
        {
            return p1.getLast()<p2.getLast();
        }
    };
    void ArrayInOb::sort()
    {
        std::sort(v.begin(),v.end(), compPhrase());
    }
    Et, enfin, si ce qui t'intéresse plus que tout, ce sont les valeurs triées, il est peut être intéressant d'envisager de gérer les phrases avec une autre collection... le std::set ou le std::multiset, par exemple
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Et bien, merci beaucoup koala01, j'imagine pas le temps que ça a du te prendre

    Je vais regarder et corriger tout cela minutieusement, je te tiens au courant

Discussions similaires

  1. trier un fichier particulier command sort shell
    Par Mistervanhalen dans le forum Shell et commandes GNU
    Réponses: 9
    Dernier message: 22/06/2008, 19h56
  2. Tri d'un fichier texte, commande sort
    Par fantomas261 dans le forum Shell et commandes GNU
    Réponses: 4
    Dernier message: 16/04/2007, 17h01
  3. Commande sort et ses options
    Par devAd dans le forum Shell et commandes GNU
    Réponses: 5
    Dernier message: 28/11/2006, 12h53
  4. Commande SORT Problème
    Par Spyco dans le forum Shell et commandes GNU
    Réponses: 5
    Dernier message: 11/05/2006, 12h59
  5. Commande sort
    Par Spyco dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 19/01/2006, 11h53

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