Partage
  • Partager sur Facebook
  • Partager sur Twitter

Fonction qsort ne marche pas ?

    13 septembre 2020 à 20:01:55

    Bonjour, 

    J'essaye de faire un programme qui trie une liste de chaine de caractere via la fonction qsort et j'ai utilisé le code du man qsort et je l'ai légèrement adapter pour ne pas passer par les arguments du programmes mais par des scanfs : resultat le qsort CRASH sans aucun message.

    Sachant qu'il ne renvoit pas de message d'erreur, je ne sais où est le problème.

    Merci pour votre aide

    CODE :

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <assert.h>
    
    static int cmpstringp(const void *p1, const void *p2)
    {
        /* Les arguments de cette fonction sont des « pointeurs de
           pointeurs sur des char », mais les arguments de strcmp(3)
           sont des « pointeurs sur des char », d'où le transtypage
           et l'utilisation de l'astérique */
    
        return strcmp(* (char * const *) p1, * (char * const *) p2);
    }
    
    /*
    
    5
    papier
    carton
    verre
    plastique
    fer
    
    */
    
    int main() {
        int nbElement;
        scanf("%d\n",&nbElement);
    
        char mots[100][101];
    
        for (int i = 0;i < nbElement;i++)
            if (scanf("%s",mots[i]) == -1)
                printf("pb !!!!\n");
        
        for (int i = 0;i < nbElement;i++)
            printf("mots[%d] = %s\n",i,mots[i]);
        
        qsort(mots, nbElement, sizeof(char *), cmpstringp);
    
        printf("------------------");
        
        for (int i = 0;i < nbElement;i++)
            printf("mots[%d] = %s\n",i,mots[i]);
    
        return 0;
    }



    • Partager sur Facebook
    • Partager sur Twitter
      13 septembre 2020 à 20:30:35

      Hello,

      La taille d'un élément est sizeof(mot[0]), pas sizeof(char *)

      -
      Edité par edgarjacobs 13 septembre 2020 à 20:33:51

      • Partager sur Facebook
      • Partager sur Twitter

      On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

        13 septembre 2020 à 20:55:30

        Salut,

        J'ai modifier mais ca n'a rien changé :( .

        • Partager sur Facebook
        • Partager sur Twitter
          13 septembre 2020 à 21:55:31

          #include <stdio.h>
          #include <stdlib.h>
          #include <string.h>
          
          static int cmpstringp (void const *a, void const *b)
          {
             return strcmp ((const char*)a, (const char*)b);
          }
          
          int main(void)
          {
              int nbElement=5;
          
              char mots[10][50]={"papier", "carton", "verre", "plastique", "fer"};
          
              for (int i = 0; i < nbElement; i++) printf("mots[%d] = %s\n", i, mots[i]);
          
              qsort(mots, nbElement, 50, cmpstringp);
          
              printf("------------------\n");
          
              for (int i = 0; i < nbElement; i++) printf("mots[%d] = %s\n", i, mots[i]);
          
              return 0;
          }

          -
          Edité par rouloude 13 septembre 2020 à 22:29:25

          • Partager sur Facebook
          • Partager sur Twitter
            13 septembre 2020 à 22:02:11

            0. Ah tu as raison, la fonction qsort ne marche pas, elle est cassée, tu viens de le découvrir, en fait elle est là depuis 40 ans, mais personne ne s'en sert et tu viens de découvrir qu'elle ne marche pas. C'est un secret, ne le répète pas surtout. #UnixHasNeverExisted

            1. Tu devrais faire voir ce qui n'a pas marché

            2. En mettant l'appel

            qsort(mots, nbElement, 101, cmpstringp);
            

            et en remplaçant la fonction de comparaison par

            static int cmpstringp(const void *p1, const void *p2)
            {
               return 0;
            }
            

            certes, le résultat est faux, mais ça ne plante plus.

            Conclusion ton problème est dans la fonction de comparaison, où tu bidouilles artistiquement des tas de machins avec des étoiles. Et c'est pas une bonne idée d'aller accuser ce pauvre qsort : le problème vient juste de ce que tu as écrit.

            Reprenons calmement.

            - ta fonction de comparaison, elle reçoit des pointeurs p1, p2 sur les données à comparer. De type const void * pour être générique.

            - en fait tes pointeurs, ils pointent sur des caractères. Et la fonction strcmp, elle utilise des pointeurs sur des caractères constants , parce que

              int strcmp(const char *s1, const char *s2);
            


            Donc c'est pas compliqué, faut juste convertir :

            static int cmpstringp(const void *p1, const void *p2)
            {
            	const char *s1 = p1;
            	const char *s2 = p2;
            	return strcmp(s1, s2);
            }






            • Partager sur Facebook
            • Partager sur Twitter
              13 septembre 2020 à 22:52:20

              Salut,

              En plus, le commentaire de ta fonction me fait vachement peur, car, je site

              MrsSniperMrsniper a écrit:


              static int cmpstringp(const void *p1, const void *p2)
              {
                  /* Les arguments de cette fonction sont des « pointeurs de
                     pointeurs sur des char », mais les arguments de strcmp(3)
                     sont des « pointeurs sur des char », d'où le transtypage
                     et l'utilisation de l'astérique */
                  
              }
              

              Car, si je comprends bien ton commentaire, p1 et p2 ont beau être transmis sous la forme de void *(autrement dit des pointeur sur void, pour raison de généricité sans doute), il s'agit en réalité de const char **, vu que ut parle explicitement de "pointeurs de pointeurs sur des char".

              Or, tu les transtype en pointeur sur char( (const char *) p1 et (const char *) p2) sans pour autant aller chercher ce qui pointé par ton pointeur de pointeur, et qui devrait te permettre d'accéder au pointeur "simple".

              • Partager sur Facebook
              • Partager sur Twitter
              Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                14 septembre 2020 à 7:39:08

                L'erreur, c'est de croire que

                char t[10][20];

                serait un tableau de pointeurs sur des  (suites de) caractères.

                -
                Edité par michelbillaud 14 septembre 2020 à 7:40:04

                • Partager sur Facebook
                • Partager sur Twitter

                Fonction qsort ne marche pas ?

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown