Texte en langage c

scarface15 -  
Emmanuel Delahaye Messages postés 107 Date d'inscription   Statut Membre Dernière intervention   -
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;
}
A voir également:

9 réponses

Pacorabanix Messages postés 3248 Date d'inscription   Statut Membre Dernière intervention   663
 
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.
0
chuka Messages postés 965 Date d'inscription   Statut Membre Dernière intervention   378
 
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;
}

@+
0
Pacorabanix Messages postés 3248 Date d'inscription   Statut Membre Dernière intervention   663
 
Salut, si le texte contient plusieurs espaces à la suite ton programme ne marche pas.
0
chuka Messages postés 965 Date d'inscription   Statut Membre Dernière intervention   378
 
c'est pas faux...;)
0
scarface15
 
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.....@+
0
Pacorabanix Messages postés 3248 Date d'inscription   Statut Membre Dernière intervention   663
 
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.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Emmanuel Delahaye Messages postés 107 Date d'inscription   Statut Membre Dernière intervention   7
 
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').
0
scarface15
 
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
@+
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
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.
0
scarface15
 
slt fiddy,
dis moi ta une meilleur idée pour faire tout cela ...@+
0
chuka Messages postés 965 Date d'inscription   Statut Membre Dernière intervention   378
 
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;
}

@+
0
Emmanuel Delahaye Messages postés 107 Date d'inscription   Statut Membre Dernière intervention   7
 
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;
}
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846 > Emmanuel Delahaye Messages postés 107 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour,

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,
0
Emmanuel Delahaye Messages postés 107 Date d'inscription   Statut Membre Dernière intervention   7 > fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention  
 
Possible, 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 ...
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
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.
0