Texte en langage c

Bonjour,
je suis sur le point de saisir un texte et puis compter le nombre de mots de ce texte , alors voila mon code qui me rend toujours le nombre de mots=1, s'il vous aidez moi c'est urgent merci...@+

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
int leng;
int nb_mots=0;
int i;
char text[1000];

printf("faite entrez votre texte\n");

gets(text);
printf("la longueur de votre texte = %d\n", strlen(text));

leng = strlen(text);

for( i = 0;i<leng;i++)
{
if (text[i] != " ")
{
nb_mots = nb_mots + 1;

for (i; i<leng; i++)
{
if(text[i]==" ") break;
}
}
}

printf("votre texte contient %d mot(s)\n",nb_mots);

return 0;
}
Configuration: Windows Vista
Firefox 3.5.6

9 réponses

  • Votes
  • Date
  • Date décroissante
  1. juste pour l'apparence, puisque tu utilises le i d'avant, tu n'as pas besoin d'écrire "i" au début :

    for (; i<leng; i++)
    {
    if(text[i]==" ") break;
    }

    Ensuite, le noeud du problème :

    if (text[i] != " ")

    est incorrect.

    D'ailleurs, les deux fois où tu écris ça personnellement j'ai un Warning de mon compilateur :
    [Warning] comparison between pointer and integer 


    tu cherches à tester une égalité de deux caractères.
    Or " " n'est pas un caractère, c'est une chaine ! A cause des guillemets doubles : "
    Pour un caractère c'est guillemets simple :
    if (text[i] != ' ')

    voilà, une toute petite erreur difficile à voir... sauf si tu regardes les warnings de ton compilo ! ;)
    (Je dois dire que sans le warning j'aurai mis du temps à la trouver aussi...)

    PS: pour l'explication du message d'erreur, un char (caractère), est en fait pour le c une sorte de nombre entier (integer). Et la chaine, c'est un tableau de char, qui est plus ou moins comme un pointeur (pointer), d'où le message du warning : comparaison entre un entier et un pointeur.
    1. salut,
      tu peux essayer ca:
      int main()
      {
      int leng;
      int nb_mots=0;
      int i;
      char* text=(char*)malloc(1000);
      printf("faite entrez votre texte\n");
      gets(text);
      printf("la longueur de votre texte = %d\n", strlen(text));
      while (*text)
      {
          if (*text==' ')
              nb_mots++;
          text++;
      }
      printf("votre texte contient %d mot(s)\n",nb_mots+1);
      return 0;
      }
      

      @+
      1. Salut, si le texte contient plusieurs espaces à la suite ton programme ne marche pas.
    2. merci beaucoup pour vos réponses , et pour chuka slt j'ésper que tu vas bien , alors voila j'ai essayé ta solution et ca marche très bien , et la j'ai juste une demande pour vous comme je suis et train de travaillez sur mon projet de fin d'étude et ce projet consiste a réaliser un traitement de texte je te demande juste si ta une idée ou pas merci d'avance.....@+
      1. ton programme avant était très bien ! c'est juste les " " à remplacer par des ' ' .

        sinon pour un traitement de texte (genre les vieux word sur dos) ben c'est pas facile... si tu veux une interface agréable par exemple.

        mais sinon tu peux faire des choses comme :

        Ajouter du texte à la fin. Ajouter du texte au début. Permettre de chercher un mot dans le texte (ou amélioré : dire combien de fois il y a tel mot, et à quel endroit ils sont).
        Et aussi : sauvegarder ton texte dans un fichier, et permettre de charger un texte lu d'un fichier.

        Tu peux aussi améliorer un peu ton comptage de mot en prenant en compte la ponctuation comme les espaces.

        Si qq'un écrit "Salut,ca va", ton code compte 2 mots alors qu'il y en a 3.
    3. Déjà, il faut corriger ça :
      
      -------------- Build: Debug in hello ---------------
      
      Compiling: main.c
      Linking console executable: bin\Debug\hello.exe
      C:\dev\hello\main.c:6: warning: function declaration isn't a prototype
      C:\dev\hello\main.c: In function `main':
      C:\dev\hello\main.c:21: warning: comparison between pointer and integer
      C:\dev\hello\main.c:27: warning: comparison between pointer and integer
      C:\dev\hello\main.c:25: warning: statement with no effect
      Output size is 18.89 KB
      Process terminated with status 0 (0 minutes, 7 seconds)
      0 errors, 4 warnings
      

      soit
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      int main (void) /* -ed- */
      {
         int leng;
         int nb_mots = 0;
         int i;
         char text[1000];
      
         printf ("faite entrez votre texte\n");
      
         gets (text);
         printf ("la longueur de votre texte = %d\n", strlen (text));
      
         leng = strlen (text);
      
         for (i = 0; i < leng; i++)
         {
            if (text[i] != ' ')  /* -ed- */
            {
               nb_mots = nb_mots + 1;
      
               for (; i < leng; i++) /* -ed- */
               {
                  if (text[i] == ' ')
                     break;
               }
            }
         }
      
         printf ("votre texte contient %d mot(s)\n", nb_mots);
      
         return 0;
      }
      

      Ce qui donne
      faite entrez votre texte
      Hello wild world
      la longueur de votre texte = 16
      votre texte contient 3 mot(s)
      
      Process returned 0 (0x0)   execution time : 7.927 s
      Press any key to continue.
      

      Mais on ne doit pas utiliser gets(), qui est un bug bien connu (trou de sécurité), mais fgets() et gérer convenablement les fins de lignes ('\n').
      1. voila le code correct
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>

        int main()
        {
        int nb_mots=0;
        char* text=(char*)malloc(1000);
        printf("faite entrez votre texte,verifiez que votre texte termine par un point\n");
        gets(text);
        printf("\n");
        while (*text!='.')
        {
        if (*text==' ')
        nb_mots++;
        text++;
        }

        printf("\n");
        printf("votre texte contient %d mot(s)\n",nb_mots+1);
        return 0;

        }

        mais il y a un problème si on a des blancs au début du texte
        @+
        1. Contributeur
          Salut
          Euh, très dangereux comme technique.
          Tu alloues une zone dans le heap et tu modifies le pointeur qui pointe dessus. Il ne faut pas faire ça, sinon tu ne peux plus désallouer la zone. Il vaut mieux utiliser un autre pointeur. Et ne pas oublier de désallouer avec free.
          Ensuite comme il a été dit par Emmanuel Delahaye, l'utilisation de gets est à proscrire.
      2. slt fiddy,
        dis moi ta une meilleur idée pour faire tout cela ...@+
        1. Salut,
          tu peux essayer cela:
          int main()
          {
          int leng;
          int nb_mots=0;
          int i;
          char* text=(char*)malloc(1000);
          char *p=text;
          printf("faite entrez votre texte\n");
          fgets(text,1000,stdin);
          printf("la longueur de votre texte = %d\n", strlen(text));
          if (*p==' ')
              while(*(p++)==' ');
          if (*p)
          {
              while (*p)
              {
                  if (*(p++)==' ' && *(p)!=' ')
                      nb_mots++;
              }
              printf("votre texte contient %d mot(s)\n",nb_mots+1);
          }
          else
              printf("votre texte contient 0 mot\n");
          
          free(text);
          return 0;
          }
          

          @+
          1. Euh, pas complet ...
            
            -------------- Build: Debug in hello ---------------
            
            Compiling: main.c
            Linking console executable: bin\Debug\hello.exe
            C:\dev\hello\main.c:2: warning: function declaration isn't a prototype
            C:\dev\hello\main.c: In function `main':
            C:\dev\hello\main.c:6: warning: implicit declaration of function `malloc'
            C:\dev\hello\main.c:8: warning: implicit declaration of function `printf'
            C:\dev\hello\main.c:9: warning: implicit declaration of function `fgets'
            C:\dev\hello\main.c:9: error: `stdin' undeclared (first use in this function)
            C:\dev\hello\main.c:9: error: (Each undeclared identifier is reported only once
            C:\dev\hello\main.c:9: error: for each function it appears in.)
            C:\dev\hello\main.c:10: warning: implicit declaration of function `strlen'
            C:\dev\hello\main.c:25: warning: implicit declaration of function `free'
            C:\dev\hello\main.c:3: warning: unused variable `leng'
            C:\dev\hello\main.c:5: warning: unused variable `i'
            Process terminated with status 1 (0 minutes, 1 seconds)
            3 errors, 8 warnings
            

            Ceci compile sans erreurs :
            #include <stdio.h>
            #include <stdlib.h>
            #include <string.h>
            
            int main (void)
            {
               int nb_mots = 0;
               char *text = malloc (1000);
               char *p = text;
               printf ("faite entrez votre texte\n");
               fgets (text, 1000, stdin);
               printf ("la longueur de votre texte = %d\n", strlen (text));
               if (*p == ' ')
                  while (*(p++) == ' ');
               if (*p)
               {
                  do
                  {
                     if (*(p++) == ' ' && *(p) != ' ')
                        nb_mots++;
                  }
                  while (*p);
                  printf ("votre texte contient %d mot(s)\n", nb_mots + 1);
               }
               else
                  printf ("votre texte contient 0 mot\n");
            
               free (text);
               return 0;
            }
            

            Mais ça n'en fait pas un code correct pour autant.

            - Pourquoi allouer une taille fixe ?
            - Admettons que ce soit justifié (réallocation, par exemple), il faut vérifier si l'allocation a réussi avant d'utiliser la zone allouée.
            - La taille allouée devrait être une constante littérale (voire une variable en cas de réallocation).

            if (*(p++) == ' ' && *(p) != ' ')

            est difficile à comprendre, et j'ai un doute sur la portabilité... Il serait beaucoup plus clair pour tout le monde, de séparer le test de l'incrémentation...

            if (p[0] == ' ' && p[1] != ' ')
            {
            }
            p++;
            


            Par exemple, ceci fonctionne correctement :
            #include <stdio.h>
            #include <stdlib.h>
            #include <string.h>
            
            #define SIZE 100
            
            static void fclean (char *line, FILE * fp)
            {
               char *p = strchr (line, '\n');
               if (p != NULL)
               {
                  *p = 0;
               }
               else
               {
                  int c;
                  while ((c = fgetc (fp)) != '\n' && c != EOF)
                  {
                  }
               }
            }
            
            int main (void)
            {
               int nb_mots = 0;
               char *text = malloc (SIZE);
               if (text != NULL)
               {
                  char *p = text;
                  printf ("Saisir un texte (max %d car.)\n", SIZE - 2);
                  fgets (text, SIZE, stdin);
                  fclean (text, stdin);
                  printf ("la longueur du texte est de %d car.\n", strlen (text));
            
                  /* skip blanks */
                  if (*p == ' ')
                     while (*(p++) == ' ');
            
                  if (*p)
                  {
                     nb_mots = 1;
                     do
                     {
                        if (p[0] == ' ' && p[1] != ' ')
                        {
                           nb_mots++;
                        }
                        p++;
                     }
                     while (*p);
                  }
                  printf ("votre texte contient %d mot%s\n", nb_mots,
                          nb_mots > 1 ? "s" : "");
            
                  free (text);
               }
               return 0;
            }
            
          2. Contributeur
            @Emmanuel DelahayeBonjour,

            if (p[0] == ' ' && p[1] != ' ')
            Jolie comme astuce, mais cela ne marche pas si la chaîne se termine par un ou plusieurs espaces.

            Cdlt,
          3. @fiddyPossible, je n'ai fait que transcrire de manière claire le code du P.O. Je ne sais même pas à quoi il sert, mais lui doit le savoir ...
        2. Contributeur
          Si chacun donne sa proposition, je donne la mienne ^^ :
          #include <stdio.h>
          #include <stdlib.h>
          #include <string.h>
          
          #define MAX 160
          
          static char* lireTexte(char * const mot, const int szMot) {
              if (fgets(mot, szMot, stdin) == NULL) {
                  return NULL;
              } 
              else {
                  char *p = strchr(mot, '\n');
          
                  if (p != NULL) {
                      *p = '\0';
                  } 
                  else {
                      int c;
          
                      while ((c=getchar()) != '\n' && c != EOF);
                  }
          
                  return mot;
              }
          }
          
          static int isPonctuation(const char car) {
              return strchr("',\". ", car) ? 1 : 0;
          }
          
          int main(void) {
              char mot[MAX];
          
              printf("entrez votre texte : ");
              fflush(stdout);
          
              if (lireTexte(mot, sizeof mot) == NULL) {
                  fputs("erreur de lecture\n", stderr);
                  return EXIT_FAILURE;
              }
              else {
                  int nbMots;
                  const char *p = mot;
              
                  nbMots=0;
                  while (*p != '\0') {
                      if (isPonctuation(*p)) {
                          while (*(++p) && isPonctuation(*p));
                      }
                      else {
                          nbMots++;
                          while (*(++p) && ! isPonctuation(*p));
                      }
                  }
          
                  printf("il y a %d mot(s) dans la phrase\n", nbMots);
              }
          
              return 0;
          }
          

          Bien sûr c'est loin d'être parfait, il reste des axes d'améliorations comme prendre en compte les caractères au-delà de la taille du buffer. Etc.
          Voilà, si tu as des questions sur le code, n'hésite pas.