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

MFC Discussion :

Trier une CStringList


Sujet :

MFC

  1. #1
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    650
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 650
    Par défaut Trier une CStringList
    Bonjour,

    j'essai de trier un CStringList avec le code qui suit, mais j'ai une erreur en plein milieu du tri, j'essai de tracer et je comprend pas pourquoi quand je fait un RemoveAt, l'element semble bien supprimé car le count affiche 1 de moins, mais la boucle des pointeurs passe toujours sur les X elements du début.

    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
    void SortCStringList(CStringList & cslListe)
    {
    	POSITION pos, memPos, minPos;
    	CStringList cslTmp;
    	CString ligne, ligneMin;
    	int i, 
    		ln = cslListe.GetCount();
     
    	for (i=0;i<ln; i++)
    	{
    		ligneMin = cslListe.GetHead();
    		for( pos = cslListe.GetHeadPosition(); pos != NULL; )
    		{
    			memPos = pos;
    			ligne = cslListe.GetNext( pos );
    			if (ligne < ligneMin)
    			{
    				ligneMin = ligne;
    				minPos = memPos;
    			}
    		}
    		cslListe.RemoveAt(minPos);
    		cslTmp.AddTail(ligneMin);
    	}
    	for( pos = cslTmp.GetHeadPosition(); pos != NULL; )
    	{
    		cslListe.AddTail(cslTmp.GetNext(pos));
    	}
     
    }
    Si vous pouviez m'aider à y voir + clair !

    merci

  2. #2
    Membre Expert
    Avatar de la drogue c'est mal
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    2 253
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 2 253
    Par défaut
    c'est parce que ln contient le nombre d'élément initial et vu que tu supprimes au fur et à mesure bah ca plante :

    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
     
     
    ligneMin = cslListe.GetHead();  // si cslListe est vide, ca renvoie null donc ca ne rentre pas dans le for donc ligneMin et minPos ne sont plus initialisés
          for( pos = cslListe.GetHeadPosition(); pos != NULL; ) 
          { 
             memPos = pos; 
             ligne = cslListe.GetNext( pos ); 
             if (ligne < ligneMin) 
             { 
                ligneMin = ligne; 
                minPos = memPos; 
             } 
          } 
     
    // pas de test sur la valeur minPos donc tu vas supprimer quelques chose qui n'existe plus si pos == NULL donc risque de plantage
          cslListe.RemoveAt(minPos); 
          cslTmp.AddTail(ligneMin);

  3. #3
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    650
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 650
    Par défaut
    ben, jpiges pas la....

    Ln permet de boucler X fois, X etant le nombre de cstring que contient ma liste, Apres je ne me sert plus de Ln, rien n'estindexe par rapport a Ln.

    si ma liste contient 10 element,
    je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Pour i de 0 à Ln-1
     
      recherche du + petit dans la liste
     
      ajout de cet element a ma liste temporaire
     
      suppression de l'element dans la liste
     
    fin de boucle
     
    copie de la liste temporaire dans la liste de retour
    et dans la recherche de + petit, je me possitionne au debut de la liste et la parcoure jusqu'à sa fin validé par NULL et non Ln

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    650
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 650
    Par défaut
    tu vois pas alors ?

  5. #5
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Le problème c'est que tu fais ln = cslListe.GetCount(); et qu'après tu enlèves des éléments. Donc, au bout d'un moment, tu va taper dans le vide.
    Tu dois donc utiliser une boucle while et remettre à jour ton ln avant chaque nouvelle boucle.

    Hope it helps.

  6. #6
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    650
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 650
    Par défaut
    ben justement non (selon moi),

    j'ai dis element,

    je boucle 10 fois en en supprimant qu'un à la fois, donc à la fin,
    elle est vide mais je sort de la boucle

  7. #7
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    bon, prenons un exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    POSITION pos;
    CStringList maListe;
    maListe.AddTail("1");
    maListe.AddTail("2");
    maListe.AddTail("3"); //j'ai donc une liste avec trois éléments: "1", "2" et "3"
    int size = maListe.GetCount();
    for (int i=0; i<size; i++) //ici, size = 3
    {
       pos = maListe.FindIndex(2); //on se positionne sur le 2eme élément
       maListe.RemoveAt(pos); //on efface le dernier élément
    }
    Maintenant, exécutons pas à pas:
    -> Avant de rentrer dans la boucle:
    maListe={"1","2","3"}
    -> après la 1ere boucle:
    maListe={"1","3"}
    -> après la 2eme boucle:
    maListe={"1"}
    ->On rentre maintenant dans la 3eme boucle:
    maListe.FindIndex(2); retourne NULL, puisqu'il n'y a plus de 2eme élément.
    =>maListe.RemoveAt(pos) <=>maListe.RemoveAt(NULL); plante!!

    get it?

  8. #8
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    650
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 650
    Par défaut
    oui mais en debut de boucle, je me repositionne au debut avec

    for( pos = cslListe.GetHeadPosition(); pos != NULL; )

    donc a chaque passage, je recommence du debut vers le dernier (dynamique)

  9. #9
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    mhh oui, en effet.
    Ta façon de procéder est... originale, mais bon, je ne comprends pas pourquoi ça ne marche pas.
    Quelle est l'erreur que tu reçois?
    Si tu effectuer le test sur un liste de 2 éléments, que se passe-t-il?

  10. #10
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    650
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 650
    Par défaut
    ben, quand je debug en pas à pas, la boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
          for( pos = cslListe.GetHeadPosition(); pos != NULL; )
          {
             memPos = pos;
             ligne = cslListe.GetNext( pos );
             if (ligne < ligneMin)
             {
                ligneMin = ligne;
                minPos = memPos;
             }
          }
    elle repasse par toutes les anciennes valeurs qui devrait avoir été supprimé alors que le survol de cslListe indique par count que son nombre d'élément décroit normalement,

    ligne contient bien les valeurs qui ont été supprimée successivement comme si de rien été

    c'est trop bizard !

  11. #11
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par firejocker
    c'est trop bizard !
    En effet.

    Je ne vois pas où est le problème, mais ce qui est sûr, c'est que tu fais beaucoup de choses dangereuses dans ton algo.
    La seule chose que je puisse te proposer, c'est de procéder autrement. Quelques chose comme ça:

    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
    tri(CStringList &maliste)
    {
       POSITION pos;
       CString strTmp;
       CSringList tmpliste = new CStringList(maliste); //on recopie dans une liste temporaire
       maliste.RemoveAll();
       while (!tmpListe.IsEmpty())
       {
          pos = TrouvePlusPetitElement(tmpList, strTmp);
          maliste.AddHead(strTmp);
          tmpList.RemoveAt(pos);
       }
    }
     
    POSITION TrouvePlusPetitElement(CStringList tmpList, CString &strTmp)
    {
       if (tmpList.IsEmpty()){return NULL);
       POSITION ret;
       strTmp = tmpList.GetHead();
       for (int i=0; i<tmpList.GetCount(); i++)
       {
          if (strTmp>tmpList.GetAt(tmpList.FindIndex(i)))
          {
             ret = tmpList.FindIndex(i);
             strTmp = tmpList.GetAt(tmpList.FindIndex(i)));
           }
       }
       return ret;
    }
    Je n'ai pas testé, mais c'est pour l'algo.

    Hope it helps.
    @+

  12. #12
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    650
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 650
    Par défaut
    ben, c'est ca reviens au même que mon code ca en algo,

    ma boucle qui se comporte bizarement sert a chercher le + petit, puis je l'ajoute à une nouvelle liste et le supprime de l'ancienne

    bon, ben jte remercis de l'aide et vais dans ce sens alors....

  13. #13
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    oui, ça reviens au même mais je ne fais pas les 2 trucs dangereux que tu fais, à savoir:
    - faire une boucle for sur une liste qui est modifiée dans la boucle
    - memPos = pos; (la recopie d'itérateurs est souvent hasardeuse dans la MFC )

    Sinon, ton sujet n'est pas résolu, je te suggère donc de le remettre en "non résolu", car il y a d'autres membres de developpez.com, bien plus expérimentés et futés, qui pourront certainement te répondre mieux que moi.

  14. #14
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    650
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 650
    Par défaut
    lol

    merci encore

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VB.NET] Trier une table de mon DataSet
    Par San Soussy dans le forum ASP.NET
    Réponses: 3
    Dernier message: 03/03/2005, 17h30
  2. Comment trier une DBGRID en cliquant sur une colonne
    Par sessime dans le forum Bases de données
    Réponses: 8
    Dernier message: 09/10/2004, 16h18
  3. [Debutant(e)]Trier une liste
    Par LeDébutantJava dans le forum Collection et Stream
    Réponses: 8
    Dernier message: 19/08/2004, 12h44
  4. [langage] Trier une hastable
    Par Gogoye dans le forum Langage
    Réponses: 11
    Dernier message: 03/08/2004, 16h43
  5. Créer une vue pour trier une requete UNION ?
    Par Etienne Bar dans le forum SQL
    Réponses: 3
    Dernier message: 03/01/2003, 20h22

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