Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2554 connectés 

  FORUM HardWare.fr
  Programmation
  C

  qsort

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

qsort

n°1273297
golzinne
Posté le 26-12-2005 à 14:04:43  profilanswer
 

Bonjour,
 c'est a moi d'avoir un probleme :
 
je doit trier un tableau de chaines avec qsort, en c, malheureusement la seule chose qu'il me fait, c'est mettre la premiere chaine à la derniere place. Bizarre autant qu'etrange!!
les chaines sont : (le nombre, nb_chaines, est variable mais quatre suffisent pour l'exemple)  
 
char **chaine;
 
chaine[0] = premiere
chaine[1] = deuxieme
chaine[2] = troisieme
chaine[4] = quatrieme
 
int compare_chaines(char *chaine1,char *chaine2)
{
 return strcmp (chaine1,chaine2);
}
 
qsort(chaine,nb_chaines,sizeof(*chaine),compare_chaines);
 
int j;
 
for(j=0;j<nb_chaines;j++)
{
 printf("\nchaines n %d : ",j+1);
 puts(chaine[j]);
}
voici ce qu'il m'affiche :
 
chaine 1 : deuxieme
 
chaine 2 : trosieme
 
chaine 3 : quatrieme
 
chaine 4 : premier
 
ou est mon erreur? aidez moi svp  
merci beaucoup

mood
Publicité
Posté le 26-12-2005 à 14:04:43  profilanswer
 

n°1273298
Elmoricq
Modérateur
Posté le 26-12-2005 à 14:13:00  profilanswer
 

Prototype de qsort() :
 

void  qsort(void  *base,  size_t  nel,  size_t  width,
   int (*compar)(const void *, const void *));


 
 
Sinon pour ton char **chaine, l'absence de malloc() c'est juste parce que tu as restreint l'exemple ?
 
 
EDIT : mon message n'est pas très clair : j'ai mis le prototype de qsort() pour que tu te rendes compte que l'on passait à la fonction de comparaison des pointeurs sur les éléments à comparer.


Message édité par Elmoricq le 26-12-2005 à 14:44:19
n°1273302
Emmanuel D​elahaye
C is a sharp tool
Posté le 26-12-2005 à 14:32:20  profilanswer
 

golzinne a écrit :

ou est mon erreur ?


Ton code est incomplet. Peux-tu poster un exemple compilable et réduit au minimum de ton code, par ce que telle quel, il y a tellement d'erreurs possible, que je ne sais pas par quoi commencer...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1273308
golzinne
Posté le 26-12-2005 à 14:56:43  profilanswer
 

oui, vous avez raison, ce n'est pas tres clair,voici le code :
 
#include<malloc.h>
#include<stdio.h>
#include<string.h>
#include<time.h>
#include<stdlib.h>
 
int compare_chaines(const void *chaine1,const void *chaine2) ;
int compare_chaines(const void *chaine1,const void *chaine2)
{
 return strcmp (chaine1,chaine2);
}
 
 
Main()
{
 int nb_chaines,i;
 char **chaine ;
 char tampon[256+1];
 
 
 //entrée du nombre de chaines
 printf("combien de chaines voulez vous rentrer? \n" );
 scanf("%d",&nb_chaines);  
 chaine=(char**)malloc(sizeof(char*)*nb_chaines);
 
 //entrée des chaines de caractere
 if (chaine!=0)
 {
     
  scanf("%*c" );
  for(i=0;i<nb_chaines;i++)
  {
   printf("entrez une chaine :" );
   gets(tampon);
   chaine[i]=(char*)malloc(strlen(tampon)+1);
   if (chaine[i]!=0)
   {
    strcpy(chaine[i],tampon);                              
   }
  }
 }
 
        //tri
 qsort(chaine,nb_chaines,sizeof(*chaine),compare_chaines);
               
         //affichage
 for(i=0;i<nb_chaines;i++)
 {
  printf("\nchaines n %d : ",i+1);
  puts(chaine[i]);
 }
}
 

n°1273314
Elmoricq
Modérateur
Posté le 26-12-2005 à 15:30:21  profilanswer
 

Bon alors, très rapidement :
 

Code :
  1. /* malloc.h ?! pas standard... normalement malloc()  
  2.     est dans stdlib.h */
  3. #include<malloc.h>
  4. #include<stdio.h>
  5. #include<string.h>
  6. #include<time.h>
  7. #include<stdlib.h>
  8. /* inutile de prototyper une fonction dont l'imprémentation  
  9.     se trouve juste en dessous ;) */
  10. int compare_chaines(const void *chaine1,const void *chaine2) ;
  11. int compare_chaines(const void *chaine1,const void *chaine2)
  12. {
  13.     /* eh non, comme je le disais, qsort() t'envoie des POINTEURS
  14.         vers tes elements a comparer... donc tes const void *
  15.         cachent en fait des... const char ** ! */
  16. return strcmp (chaine1,chaine2);
  17. }
  18. /* Main() ?! Avec un 'm' majuscule ?!
  19.     Deux prototypes standards de main() :
  20.         int main(void);
  21.         int main(int argc, char **argv); */
  22. Main()
  23. {
  24. int nb_chaines,i;
  25. char **chaine ;
  26. char tampon[256+1];
  27. //entrée du nombre de chaines
  28. printf("combien de chaines voulez vous rentrer? \n" );
  29.         /* bof : scanf() c'est une fonction a deconseiller aux debutants,
  30.             elle n'est pas triviale a utiliser.
  31.             Vois plutot fgets() pour la saisie, et strtol() pour la conversion
  32.             en nombre  
  33.         */
  34. scanf("%d",&nb_chaines);
  35.         /* le cast est inutile, et on peut s'afranchir du typage dans le  
  36.             sizeof, ce qui nous permet de rendre le code plus flexible :
  37.             chaine = malloc( nb_chaines * sizeof *chaine);
  38.             De plus, qu'arrive-t-il si nb_chaines est negatif ? ;)  
  39.         */
  40. chaine=(char**)malloc(sizeof(char*)*nb_chaines);
  41. //entrée des chaines de caractere
  42.         /* Dans un contexte pointeur, on teste avec NULL, et non avec 0 :
  43.                 if ( chaine != NULL )
  44.             Voire :
  45.                 if ( chaine )  
  46.         */
  47. if (chaine!=0)
  48. {
  49.  scanf("%*c" );
  50.  for(i=0;i<nb_chaines;i++)
  51.  {
  52.                         /* Le souci c'est que toute ligne ne se terminant pas par
  53.                             un saut de ligne attendra peut-etre dans le buffer de
  54.                             sortie avant d'etre affichee.
  55.                             Ce qui veut dire que tu ne la verras peut-etre qu'APRES
  56.                             que tu aies tape [ENTREE] !
  57.                             Toute sortie ne se terminant pas par un saut de ligne
  58.                             devrait se voir suivre d'un :
  59.                                 fflush(flux_de_sortie);
  60.                             (ici, flux_de_sortie == stdout)
  61.                         */
  62.   printf("entrez une chaine :" );
  63.                         /* AAAAAAAAAAAAAAAAAAAAAARRRRRRRRGH !!
  64.                             NE JAMAIS UTILISER gets() !
  65.                             gets() est obsolete depuis des annees, et pour une  
  66.                             bonne raison : il n'y a aucun controle de depassement
  67.                             de capacite avec !
  68.                             Cette fonction est a abolir de ton vocabulaire.
  69.                             Pour toujours.
  70.                         */
  71.   gets(tampon);
  72.   chaine[i]=(char*)malloc(strlen(tampon)+1);
  73.   if (chaine[i]!=0)
  74.   {
  75.    strcpy(chaine[i],tampon);                             
  76.   }
  77.  }
  78. }
  79.         //tri
  80. qsort(chaine,nb_chaines,sizeof(*chaine),compare_chaines);
  81.              
  82.          //affichage
  83. for(i=0;i<nb_chaines;i++)
  84. {
  85.                 /* pourquoi puts() en plus du printf() ?
  86.                         printf("\nchaines n°%d : %s", i+1, chaine[i] );
  87.                 */
  88.  printf("\nchaines n %d : ",i+1);
  89.  puts(chaine[i]);
  90. }
  91. }


n°1273361
golzinne
Posté le 26-12-2005 à 17:20:20  profilanswer
 


 

Citation :

int compare_chaines(const void *chaine1,const void *chaine2) ;
int compare_chaines(const void *chaine1,const void *chaine2)
{
    /* eh non, comme je le disais, qsort() t'envoie des POINTEURS
        vers tes elements a comparer... donc tes const void *
        cachent en fait des... const char ** ! */
 return strcmp (chaine1,chaine2);
}


 
ok, g pris note des modification, mais je ne comprend pas ce que je dois mettre a la place de mes const viod *chaine1 et const void *chaine2

Message cité 1 fois
Message édité par golzinne le 26-12-2005 à 17:21:59
n°1273363
Elmoricq
Modérateur
Posté le 26-12-2005 à 17:22:58  profilanswer
 

Rien, c'est ce qu'attend qsort() de ta fonction.
 
Par contre tu dois déréférencer ces paramètres pour les passer à strcmp().
 
A l'heure actuelle strcmp() s'attend à des const char*, et toi tu lui passes des const char **.

n°1273377
Emmanuel D​elahaye
C is a sharp tool
Posté le 26-12-2005 à 18:00:41  profilanswer
 

golzinne a écrit :

je ne comprend pas ce que je dois mettre a la place de mes const void *chaine1 et const void *chaine2


Ne modifie pas les paramètres (à part les noms !). Simplement ceux-ci reçoivent les adresses des 2 objets dans le tableau que l'on veut comparer. Les objets étant de type char*, leurs adresses sont de type char **. Pour déréférencer correctement les données, il faut donc initialiser des pointeurs locaux du bon type (soit ... char ** !)

Code :
  1. char **pp1 = chaine1; /* mauvais choix de nom, il faudrait en fait inverser) */
  2. char **pp2 = chaine2;


ensuite le début des chaines se trouve à *p1 et *p2 (ou p1[0] et p[2])? C'est cette valeur que l'on doit passer à strcmp() :  

Code :
  1. return strcmp (*pp1,*pp2);



---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1273709
golzinne
Posté le 27-12-2005 à 14:20:21  profilanswer
 

OK, je suis parvenu a y arriver grace a tous ces bons conseil. Et en plus ça m'a permit de comprendre l'astuce des pointeurs de pointeurs? Je vais aborder l'examen avec moins de craintes maintenant.
 
Merci beaucoup.

n°1278941
matafan
Posté le 08-01-2006 à 03:55:55  profilanswer
 

golzinne a écrit :

je suis parvenu a y arriver


Je suis heureux d'être content pour toi.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  qsort

 

Sujets relatifs
[C++] QSort et CArray<MyClass*, MyClass*>[C++] qsort() sur des templates
urgent ! qsort en lispqsort
Problème avec la fonction qsort() en langage C ! 
Plus de sujets relatifs à : qsort


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)