Texte en langage c

Fermé
scarface15 - 23 janv. 2010 à 15:51
Emmanuel Delahaye Messages postés 107 Date d'inscription jeudi 18 juin 2009 Statut Membre Dernière intervention 17 juillet 2019 - 24 janv. 2010 à 16:23
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;
}

9 réponses

Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 661
23 janv. 2010 à 16:06
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 samedi 11 octobre 2008 Statut Membre Dernière intervention 29 juillet 2010 378
23 janv. 2010 à 16:10
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 jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 661
23 janv. 2010 à 16:17
Salut, si le texte contient plusieurs espaces à la suite ton programme ne marche pas.
0
chuka Messages postés 965 Date d'inscription samedi 11 octobre 2008 Statut Membre Dernière intervention 29 juillet 2010 378
23 janv. 2010 à 16:17
c'est pas faux...;)
0
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 jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 661
23 janv. 2010 à 16:25
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 jeudi 18 juin 2009 Statut Membre Dernière intervention 17 juillet 2019 7
23 janv. 2010 à 17:29
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
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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
23 janv. 2010 à 18:04
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
slt fiddy,
dis moi ta une meilleur idée pour faire tout cela ...@+
0
chuka Messages postés 965 Date d'inscription samedi 11 octobre 2008 Statut Membre Dernière intervention 29 juillet 2010 378
24 janv. 2010 à 08:44
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 jeudi 18 juin 2009 Statut Membre Dernière intervention 17 juillet 2019 7
24 janv. 2010 à 09:36
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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844 > Emmanuel Delahaye Messages postés 107 Date d'inscription jeudi 18 juin 2009 Statut Membre Dernière intervention 17 juillet 2019
24 janv. 2010 à 15:59
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 jeudi 18 juin 2009 Statut Membre Dernière intervention 17 juillet 2019 7 > fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022
24 janv. 2010 à 16:23
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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
24 janv. 2010 à 15:36
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