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 :

Trouver le nombre de mots


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    102
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 102
    Par défaut Trouver le nombre de mots
    bonjour a tous

    voici mon probleme, j'ai une chaine de caractere dont j'aimerais savoir combien de mot contient cette chaine.

    je m'explique:

    chaine="bdu;ramasse;boule"

    il y a donc 3 mot dans ma chaine

    mes mots sont separer par des ";"

    j'ai penser a compter le nombre de ";" puis de lui ajouter 1, mais sans succes

    quelqu'un aurait-il une solution

  2. #2
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Salut !


    Y'a un code source sur la page source mais cela concerne le nombre de mots dans un fichier, il y'a donc une ou deux petites modifs à faire mais rien de vraiment violent: http://c.developpez.com/sources/c/?page=V

    Je me dit quand même que ta solution devrait également fonctionner !
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  3. #3
    Membre expérimenté Avatar de Ksempac
    Inscrit en
    Février 2007
    Messages
    165
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 165
    Par défaut
    Clairement, compter le nombre de ";" et ajouter 1 fonctionne (a part le cas exceptionnel ou il y a 0 mot mais ca ca se detecte facilement)

    Donc l'erreur n'est pas dans l'algorithme, mais dans l'implémentation du code. Montres-nous donc ton code et on t'aidera a le corriger

  4. #4
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Un mot est une chaîne de caractères non vide ne contenant pas de ';'.
    A partir de là, tu peux écrire ton algo en parcourant ta chaîne caractère par caractère.
    Au démarrage tu ne lis pas un mot.
    A chaque fois que tu rencontres un ';' et que tu étais en train de lire un mot, tu trouves un mot de plus et tu n'es plus en train de lire un mot.
    Mon propos est peut-être un peu obscur, mais il décrit l'algo que tu peux utiliser.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  5. #5
    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 acik59
    voici mon probleme, j'ai une chaine de caractere dont j'aimerais savoir combien de mot contient cette chaine.
    <...>quelqu'un aurait-il une solution
    Non. Par contre, si on voyait ton code à problèmes, ou pourrait t'aider à en trouver une. (Entre nous, c'est trivial...)

  6. #6
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    Peut-être une solution avec "strtok" qui permet des délimiteurs de mots plus sophistiqués ?

  7. #7
    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 dj.motte
    Peut-être une solution avec "strtok" qui permet des délimiteurs de mots plus sophistiqués ?
    Hors-sujet.

  8. #8
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    Pourtant "strtok" me parait efficace pour compter les mots d'une ligne.

    Qu'est-ce qui ne va pas dans cette option ?

    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
     
     
    #include <stdio.h>
    #include <string.h>
     
    size_t str_count_word( const char * str, const char * sep )
     { size_t nb = 0 ;
       char * s = NULL ;
       char * z = strdup( str ) ;
       if( z != NULL )
       { s = strtok( z, sep ) ;
         if( s != NULL )
         { nb += 1 ;
           while( ( s = strtok( NULL, sep ) ) != NULL )
           nb += 1 ;
         }
         free(z) ;
       }
       return nb ;
     }
     
     int main()
     { char * mot = "la;chaîne;à;découper;et;un pion;a manger" ;
       size_t nb = str_count_word( mot, ";" ) ;
       printf("%s = %02d\n", mot, nb ) ;
       return 0 ;
     }
    Cette méthode compte aussi bien les mots de la chaîne

    "aaaaa ; bbbb; ccccc; dddd "
    que

    " ; aaaa; bbbb; ccccc; ddddd;"

  9. #9
    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 dj.motte
    Pourtant "strtok" me parait efficace pour compter les mots d'une ligne.

    Qu'est-ce qui ne va pas dans cette option ?
    Déjà, ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Project   : Forums (mem)
    Compiler  : GNU GCC Compiler (called directly)
    Directory : C:\dev\forums2\
    --------------------------------------------------------------------------------
    Switching to target: default
    Compiling: main.c
    main.c: In function `str_count_word':
    main.c:21: warning: implicit declaration of function `free'
    main.c: In function `main_':
    main.c:27: warning: initialization discards qualifiers from pointer target type
    Linking console executable: console.exe
    Process terminated with status 0 (0 minutes, 1 seconds)
    0 errors, 2 warnings
    Ensuite, ça me parait bien compliqué (pas trop en fait), mais surtout tu es dépendant du comportement de strtok() (tu as pensé à faire une copie, c'est bien).

    • qui dit que tu n'est pas en train d'utiliser cette fonction ailleurs en même temps ou précédemment ? Ecrasement de la mémoire statique de strtok() : comportement indéfini.
    • comment se comporte strtok() en cas de mot vide (;;) ?

    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
    98
    99
    100
    101
    102
    103
    104
    105
     
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
     
    size_t str_count_word (const char *str, const char *sep)
    {
       size_t nb = 0;
       char *z = strdup (str);
       if (z != NULL)
       {
          char const *s = strtok (z, sep);
          if (s != NULL)
          {
             nb += 1;
             while ((s = strtok (NULL, sep)) != NULL)
                nb += 1;
          }
          free (z);
       }
       return nb;
    }
     
    int main (void)
    {
       struct test
       {
          int nt;
     
          struct
          {
             char const *s;
          }
          in;
          struct
          {
             size_t n;
          }
          out;
       };
     
       static struct test const at[] = {
          /* *INDENT-OFF* */
          {10, {""       },{0},},
          {11, {";"      },{0},},
          {12, {";;"     },{0},},
     
          {20, {"a;"     },{1},},
          {21, {";a"     },{1},},
          {22, {";a;"    },{1},},
          {23, {";;a"    },{1},},
          {24, {"a;;"    },{1},},
          {25, {";a;;"   },{1},},
          {26, {";;a;;"  },{1},},
     
          {30, {"a;b"     },{2},},
          {31, {";a;b"    },{2},},
          {32, {";a;;b"   },{2},},
          {33, {";;aa;b"  },{2},},
          {34, {"a;;b"    },{2},},
          {35, {";a;;b"   },{2},},
          {36, {";;a;;b"  },{2},},
     
          {40, {";a;b;"     },{2},},
          {41, {";a;b ;"    },{2},},
          {42, {";a; b;"    },{2},},
          {43, {";a; b ;"   },{2},},
          {44, {";a ;b;"    },{2},},
          {45, {";a ;b ;"   },{2},},
          {46, {";a ; b;"   },{2},},
          {47, {";a ; b ;"  },{2},},
          {48, {"; a;b;"    },{2},},
          {49, {"; a;b ;"   },{2},},
          {50, {"; a; b;"   },{2},},
          {51, {"; a; b ;"  },{2},},
          {52, {"; a ;b;"   },{2},},
          {53, {"; a ;b ;"  },{2},},
          {54, {"; a ; b;"  },{2},},
          {55, {"; a ; b ;" },{2},},
     
          /* *INDENT-ON* */
       };
     
       size_t i;
     
       for (i = 0; i < sizeof at / sizeof *at; i++)
       {
          struct test const *pt = at + i;
          /* D.U.T */
          size_t nb = str_count_word (pt->in.s, ";");
     
          if (nb != pt->out.n)
          {
             printf ("ERROR at test #%d\n", pt->nt);
             printf ("'%s' = %d\n", pt->in.s, nb);
             break;
          }
       }
     
       if (i == sizeof at / sizeof *at)
       {
          puts ("P A S S E D");
       }
       return 0;
    }

  10. #10
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    Emmanuel écrit :
    comment se comporte strtok() en cas de mot vide ?
    Vous voulez dire en cas de chaîne vide ?
    Dans ce cas vérifier :
    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
     
    size_t str_count_word( const char * str, const char * sep )
     { size_t nb = 0 ;
       char * s = NULL ;
       char * z = NULL ;
     
       if( str != NULL ) 
       { z = strdup( str ) ;
         if( z != NULL )
         { s = strtok( z, sep ) ;
           if( s != NULL )
           { nb += 1 ;
             while( ( s = strtok( NULL, sep ) ) != NULL )
             nb += 1 ;
           }
          free(z) ;
         }
       }
       return nb ;
     }
    Il existe aussi une fonction "strtok_r" qui prend un argument supplémentaire, afin de loger un tampon dynamique pour faire le découpage. Ce qui permet de se passer du tampon statique utilisé par "strtok".
    Je ne l'ai pas vraiment testé.


    Mais on peut se passer de "strtok" pour compter les mots séparés d'une chaîne de caractères.

    Voilà une autre version, ça a l'air de fonctionner :
    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
     
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
     
     
    size_t str_first_of( const char * z , size_t pos , const char * delim )
    { size_t len = strlen(z) ; 
      size_t i ;
      char * ptr = 0 ;
      for( i = pos ; i < len ; i++ )
      { if( 0 != ( ptr = strchr( delim, z[i] ) ) )
        return i;      
      }
      return (size_t) EOF ;
    }
     
    size_t str_first_not_of( const char * z , size_t pos , const char * delim )
    { size_t len = strlen(z) ; 
      size_t i ;
      char * ptr = 0 ;
      for( i = pos ; i < len ; i++ )
      { if( 0 == ( ptr = strchr( delim, z[i] ) ) )
        return i;
      }
      return (size_t) EOF ;
    }
     
     
    size_t  str_count_word( const char * z , const char * delim )
    { size_t nb = 0 ;
      size_t p = 0 ;
      size_t k = 0 ;
     
      while ( 1 )
      { k = str_first_not_of( z, k, delim ) ;
        if( k == EOF ) break ;
        p = str_first_of( z , k , delim ) ;
        nb += 1  ;
        k = p ;
      }
      return nb ;
    }
     
    void  do2( const char * str, const char * delim  )
    { size_t len = EOF ;
      printf("str=> %s\n", str ) ;
      printf("delim=> %s\n", delim ) ;
     
      len = str_count_word( str, delim ) ;
      printf( "str count= %d\n", len ) ;
    }
     
     
    int main( int argc , char * argv [] )
    {
      if( argc != 3 )
      { printf("Nombre de paramètres invalide\n") ;
        printf("args= \"string\"  \"delimiters\"\n" ) ;
        return 1 ;
      }
      do2( argv[1] , argv[2]  ) ;
     
      return 0 ;
    }
    On peut sans doute simplifier en remplaçant mes "str_first_of" et "str_first_not_of" par des fonctions déclarées dans "string.h" qui font le même travail. Mais je ne connais pas toutes les fonctions déclarées dans "string.h".

  11. #11
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    ce que voulait dire Emmanuel c'est que ici le PO ne voulait pas ISOLER les mots mais les COMPTER...

    Et que donc l'emploi de strtok était inutile, puisque le but n'était pas là..

    Et son algo de départ était bon..

    Cependant, vu qu'il ne nous a pas expliqué en quoi ça ne marchait pas, on est guère plus avancé sur son erreur....

    Et de plus strtok est une fonction dangereuse, puisqu'elle modifie la chaîne originale...

  12. #12
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    souviron34, vous n'avez pas lu ma deuxième version qui se passe de "strtok".

    Proposez donc votre version du comptage de mots dans une chaîne de caractères.

  13. #13
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    on ne voulait pas donner a solution mais aider le PO...

    Mais pusiqu'il ne poste pas, voici ce que je ferais :

    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
     
    int nbr ( const char * z , const char delim )
    {
      int n = 0 ;
      int m = 0 ;
      int i ;
      int len ;
     
      if ( z != NULL )
        {
           len = strlen(z) ; 
           for( i = 0 ; i < len ; i++ )
              {
                 if ( *(z+i) == delim )
                      n = n + 1 ;
                 else
                 if ( isspace(*(z+i)) )
                      m = m + 1 ;
              }
     
           if ( m != len ) /* La chaine n'est pas vide */
             {
                 if ( *(z+len-1) != delim ) /* Le dernier n'est pas le séparateur */
                      n = n + 1 ;
             }
       }
     
      return n ;
    }

  14. #14
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    Je me suis sans doute trompé. Je voyais une solution plus globale.

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 29/06/2011, 10h50
  2. Trouver le nombre de handle utiliser par un programme
    Par chuckboy dans le forum Windows
    Réponses: 1
    Dernier message: 19/12/2005, 23h38
  3. Réponses: 13
    Dernier message: 16/11/2005, 13h15
  4. Prog trouver un nombre !!!
    Par wareq dans le forum C
    Réponses: 9
    Dernier message: 04/10/2005, 08h46
  5. Compter nombre de mots dans une chaîne.
    Par xVINCEx dans le forum C++
    Réponses: 22
    Dernier message: 24/11/2004, 13h33

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