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 :

Qsort() plante


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut Qsort() plante
    Bonjour à toutes et à tous,

    Je travaille la recherche de mots (contenu dans un fichier texte) depuis un dictionnaire (également sur fichier texte). J(utilise la recherche dichotomique et le tri au moyen de qsort().
    Le source compile (Dev++) sans erreurs ni avertissements mais le programme plante lors de la lecture de la fonction. Voici mon code :

    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
    #include<ctype.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
     
    #define MAX_MOTS 100           /*  Contenu maxi du dico.  */
    #define LONG_MOT 20            /*  Nombre de caractères maxi par mot.  */ 
     
    /*
        Fonction d'affichage de "dico".
    */
     
    void afficher (char dico[])
    {
        int i;
        int n = strlen(dico);    
     
        for (i = 0; i < n ; i++)
        {
            printf ("%c", dico[i]);
        }
    }  
     
    /*
        Fonction de comparaison pour "qsort()".
    */ 
     
    int comparerMots (void const *a, void const *b)  
    {
        char const *const *pa = a;
        char const *const *pb = b;   
     
        return strcmp (*pa, *pb);
    }
     
    int main (int argc, char *argv[])
    {
        FILE *fiDico ;                                /*  Pointeurs sur fichiers texte.  */
        FILE *fiTexte ;                               
     
        int = 0 ;                                   /*  Indice courant.  */
        char ligne[LONG_MOT] = "" ;        /*  Stockage des lignes des fichiers.  */
        char dico[MAX_MOTS] = "";          /* Tableau des mots du fichier dico.  */
        char mot_texte[LONG_MOT] = "" ;    /*  Mot à rechercher.  */
        char *posMot = NULL;               /*  Pointeur pour la recherche.  */
        int nbMots = 0;                    /*  Valeur pour le nombre de mots.  */ 
     
     
        if ( argc != 2 )                        /*  Vérif. du nombre d'arguments.  */
        {
            fprintf (stderr, "Erreur de nombre d'arguments ! Usage de :\n");
            printf ("%s texte.txt\n", argv[0]);     
            exit (EXIT_FAILURE);
        }
     
        fiTexte = fopen(argv[1],"r");        /*  Vérif. d'accès au fichier.  */
        if (fiTexte == NULL)
        {
            printf ("Impossible d'ouvrir %s !\n", argv[1]);
            exit (EXIT_FAILURE);
        }
        else
        {
            fiDico = fopen("dico.dat", "r");
     
            /*  Lecture du fichier et stokage dans le tableau "dico".  */ 
            while (fgets (ligne, MAX_MOTS, fiDico) != NULL )
            {      
                nbMots++;
                strcat (dico, ligne);
            }
     
            afficher(dico);
     
            /*  Tri de "dico".  */
     
            qsort (dico, nbMots, LONG_MOT, comparerMots);	
     
            fclose(fiTexte);
            fclose(fiDico);       
        }   
        fprintf (stdout, "Appuyez sur une touche...");
        getch();
        return 0;
    }
    Je ne trouve pas l'erreur pouvant provoquer ce plantage. Pourriez-vous m'éclairer ? Merci d'avance.

  2. #2
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Salut,

    Citation Envoyé par stallaf
    Le source compile (Dev++) sans erreurs ni avertissements mais le programme plante lors de la lecture de la fonction.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     int = 0 ;                                   /*  Indice courant.  */

  3. #3
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut
    Merci ssmario2 mais c'est sans rapport.
    Ma fonction "afficher()" fonctionne c'est bien qsort qui me plante.

  4. #4
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Par défaut
    c'est normal que ca plante..

    qsort() tri un tableau.

    Tu fournis un tableau de char à qsort(), donc ca tri des char (taille=1) et non des char *....

    Donc dans ta fonction de comparaison ca plante forcément !

    il faut que 'dico' soit un tableau de char * et non pas de char....
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  5. #5
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Citation Envoyé par stallaf Voir le message
    Merci ssmario2 mais c'est sans rapport.
    Ma fonction "afficher()" fonctionne c'est bien qsort qui me plante.
    Oui, je n'avais pas vu le reste du code vu que tu ne fournis pas tous les fichiers nécessaires afin que l'on puisse reproduire l'erreur ...
    Mais comme l'indique @vicenzo tu confonds tableau de chaînes et tableaux de caractères, voici quelques liens intéressant !

    Comment créer un tableau de chaînes de caractères ?
    Du bon usage de la fonction qsort()

  6. #6
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut
    Je dois peut-être saturer, mais je ne comprend rien à ton explication vicenzo, désolé.
    Comment puis-je régler le problème ?

  7. #7
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Le dico doit être un tableau de MAX_MOTS chaînes de caractères de longueur maximum LONG_MOT.
    Tu définis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char dico[MAX_MOTS] = "";
    un tableau de MAX_MOTS caractères
    Utilise par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char dico[MAX_MOTS][ LONG_MOT];
    Alors dico[0] est la première chaîne du dico, dico[1] la seconde,etc.

    Pour afficher le dico :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void afficher (char dico[][LONG_MOT], int nbMots)
    {
        int i;    
        for (i = 0; i < nbMots ; i++) printf ("%s", dico[i]);
    }
    ....

  8. #8
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par stallaf Voir le message
    Je travaille la recherche de mots (contenu dans un fichier texte) depuis un dictionnaire (également sur fichier texte). J(utilise la recherche dichotomique et le tri au moyen de qsort().
    http://emmanuel-delahaye.developpez.com/qsort.htm

    Est-ce que tu sais ce que tu fais ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                char dico[MAX_MOTS] = ""; /* Tableau des mots du fichier dico.  */
    Tu ne vois pas l'absurdité de ce code ?

    Tu définies un tableau de char pour stocker des mots. C'est absurde. Il faut un tableau par mot :

    Par exemple (puisque tu es en format fixe) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     char dico[MAX_MOTS][LONG_MOT];
    Ensuite, c'est la panique dans les constantes ... (inversions...) Il faut
    - Bien nommer les choses
    - Utiliser le nommage pour vérifier la logique.

    Là, c'est le chaos...

    Mon dictionnaire fait plus de 130.000 (jusqu'à 26 lettres). Par contre, il est déjà trié, ça aide...

    En attendant, ceci fonctionne :
    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
    90
    91
    92
    93
    94
    95
    96
    97
     
    #include<ctype.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
     
    #define MAX_MOTS 100            /*  Contenu maxi du dico.  */
    #define LONG_MOT 30             /*  Nombre de caractères maxi par mot.  */
     
    #if 0
    #define F_DICO "dico.dat"
    #else
    #define F_DICO "\\dev\\dico\\dico_fr_maj.txt"
    #endif
     
    /*
        Fonction d'affichage de "dico".
    */
     
    void afficher (char dico[][LONG_MOT], int n)
    {
       int i;
     
       for (i = 0; i < n; i++)
       {
          printf ("%s", dico[i]);
       }
    }
     
    /*
        Fonction de comparaison pour "qsort()".
    */
     
    int comparerMots (void const *a, void const *b)
    {
       char const *pa = a;
       char const *pb = b;
     
       return strcmp (pa, pb);
    }
     
    int main (int argc, char *argv[])
    {
       int ret = EXIT_SUCCESS;
     
       if (argc > 1)                /*  Vérif. du nombre d'arguments.  */
       {
          FILE *fiTexte = fopen (argv[1], "r"); /*  Vérif. d'accès au fichier.  */
     
          if (fiTexte != NULL)
          {
             FILE *fiDico = fopen (F_DICO, "r");
             if (fiDico != NULL)
             {
                char ligne[LONG_MOT] = ""; /*  Stockage des lignes des fichiers.  */
                char dico[MAX_MOTS][LONG_MOT] = { "" }; /* Tableau des mots du fichier dico.  */
                int nbMots = 0;     /*  Valeur pour le nombre de mots.  */
     
                /*  Lecture du fichier et stokage dans le tableau "dico".  */
                while (nbMots < MAX_MOTS
                       && fgets (ligne, LONG_MOT, fiDico) != NULL)
                {
                   strcpy (dico[nbMots], ligne);
                   nbMots++;
                }
                fclose (fiDico), fiDico=NULL;
     
    printf ("nbMots = %d\n", nbMots);
                afficher (dico, nbMots);
     
    #if 1
                /*  Tri de "dico".  */
                qsort (dico, nbMots, LONG_MOT, comparerMots);
    #endif
             }
             else
             {
                perror (F_DICO);
                ret = EXIT_FAILURE;
             }
          }
          else
          {
             perror (argv[1]);
             ret = EXIT_FAILURE;
          }
          fprintf (stdout, "Appuyez sur une touche...");
          fclose (fiTexte);
       }
       else
       {
          fprintf (stderr, "Erreur de nombre d'arguments ! Usage de :\n");
          printf ("%s texte.txt\n", argv[0]);
          ret = EXIT_FAILURE;
       }
       return ret;
    }

  9. #9
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut
    Oui j'ai lu ce tuto et posté le code de la fonction comparerMots qui est un copier/coller de la votre, mais je n'ai pas du tout comprendre...

    Merci diogene mais je n'ai pas difficulté avec l'affichage (ta fonction si, elle ne fonctionne pas) . C'est qsort() qui me pose problème.

    La fonction entraine toujours le plantage après les modifications apportées à la variable "dico".

  10. #10
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par stallaf Voir le message
    La fonction entraine toujours le plantage après les modifications apportées à la variable "dico".
    J'ai donné le code qui fonctionne. Que faire de plus ?

    Ce qu'il faut comprendre avec la fonction de comparaison de qsort(), c'est que les adresses reçues sont celles des éléments que l'on est en train de trier...

  11. #11
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut
    Ouarf

    Encore une fois je me fais tirer les oreilles... A mon age c'est drôle

    Désolé mais j'ai encore pris trop de temps pour rédiger et certains avaient déjà posté. Bref, je n'avais pas pris connaissance de deux messages.
    Mais tiens, c'est déjà arrivé çà ! Il faut vraiment que je fasse attention

    Je regarde votre code ed et reviendrais vous dire.

    Une petite remarque sur la difficulté que peuvent avoir des débutants par rapport aux experts : Ils travaillent souvent sur des exercices avec un énoncé et une méthode imposée, des cours souvent trop ancien... La solution ne semble donc pas toujours la meilleure ou la plus concise.

    Merci de votre aide.

  12. #12
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    @Emmanuel : pa et pb sont-ils vraiment censés être des char const *, ou ne sont-il pas plutôt, techniquement, des char const (*)[LONG_MOT] ?

    (bref, la différence est la même qu'entre scanf("%20s", buf) et scanf("%20s", &buf), quand buf est déclaré comme un tableau de 20 char...)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #13
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut
    Merci pour le coup de mains, code et explications.
    Se former seul n'est pas toujours facile.

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

Discussions similaires

  1. [MFC] DoModal() plante
    Par barthelv dans le forum MFC
    Réponses: 3
    Dernier message: 29/07/2004, 10h56
  2. Que se passe-t-il en interne si un ROLLBACK plante ?
    Par jack554 dans le forum Administration
    Réponses: 4
    Dernier message: 07/04/2004, 12h55
  3. qsort avec un struct* ?
    Par hpfx dans le forum MFC
    Réponses: 11
    Dernier message: 06/10/2003, 18h29
  4. Réponses: 11
    Dernier message: 17/03/2003, 10h56
  5. Réponses: 2
    Dernier message: 23/10/2002, 13h38

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