Un petit programme pour compter les voyelles.

Un petit programme pour compter les voyelles. - C - Programmation

Marsh Posté le 27-11-2003 à 21:23:05    

Je cherche à compter les voyelles d'une chaine, le "cout" qui me sert à voir ce qui se passe me montre bien que le programme trouve ce qu'il faut mais il plante avant le retour de la fonction, quel est le problème ?
 

Code :
  1. int NbVoyelles (char * szPhrase)
  2. {
  3. int xvoy=0;
  4. char voyelles[]="aeiouyAEIOUY";
  5.     char *p;
  6. p=strpbrk(szPhrase,voyelles);
  7. while (*p!='\0')
  8. {
  9.  p=strpbrk(p,voyelles);
  10.  cout <<p<<endl;
  11.  p++;
  12.  xvoy++;
  13. }
  14. return(xvoy);
  15. }
  16. void main(void)
  17. {
  18. char chaine[] = "Il me semble qu il pleut dehors.";
  19.     int Voyelles;
  20. Voyelles=NbVoyelles(chaine);
  21. cout <<"La chaine est : "<<chaine<<endl;
  22. cout <<"Le nombre de voyelles est : "<<Voyelles<<endl;
  23. }


Message édité par Master_Jul le 28-11-2003 à 00:07:26
Reply

Marsh Posté le 27-11-2003 à 21:23:05   

Reply

Marsh Posté le 27-11-2003 à 21:37:31    

regarde la doc de strpbrk() (la partie sur la valeur de retour)

Reply

Marsh Posté le 27-11-2003 à 21:42:52    

Et si la phrase test n'a pas de voyelle, il va y avoir pb avec ce code...
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-11-2003 à 21:48:52    

ça retourne un pointeur sur la première occurence, j'ai essayé de me baser sur l'exemple qu'ils donnent :
 
Return Value
Returns a pointer to the first occurrence of any character from strCharSet in string, or a NULL pointer if the two string arguments have no characters in common.

Code :
  1. int main( void )
  2. {
  3.    char string[100] = "The 3 men and 2 boys ate 5 pigs\n";
  4.    char *result;
  5.    /* Return pointer to first 'a' or 'b' in "string" */
  6.    printf( "1: %s\n", string );
  7.    result = strpbrk( string, "0123456789" );
  8.    printf( "2: %s\n", result++ );
  9.    result = strpbrk( result, "0123456789" );
  10.    printf( "3: %s\n", result++ );
  11.    result = strpbrk( result, "0123456789" );
  12.    printf( "4: %s\n", result );
  13. }


 
Output
1: The 3 men and 2 boys ate 5 pigs
 
2: 3 men and 2 boys ate 5 pigs
 
3: 2 boys ate 5 pigs
 
4: 5 pigs
 
Edit : Pour le problème "d'aucune correspondance", je peux vérifier si un NULL est présent avant le while et retourner 0.


Message édité par Master_Jul le 27-11-2003 à 21:49:47
Reply

Marsh Posté le 27-11-2003 à 21:57:18    

Master_Jul a écrit :

ça retourne un pointeur sur la première occurence, j'ai essayé de me baser sur l'exemple qu'ils donnent :
 

Code :
  1. int main( void )
  2. {
  3. // snip
  4. }


 


 
et que ce passe-t-il si tu rajoutes  

Code :
  1. result = strpbrk( result, "0123456789" );
  2.        printf( "5: %s\n", result );


 
à la fin du programme d'exemple ?
 
[edit] damned le printf de crosoft est protégé contre les pointeurs nuls pour les chaines de caractères, c'est même pas drôle ca plante pas.


Message édité par SquiZZ le 27-11-2003 à 22:12:08
Reply

Marsh Posté le 27-11-2003 à 21:57:35    

c celui pour ce soir minuit ?

Reply

Marsh Posté le 27-11-2003 à 22:15:32    

SquiZz : ça renvoit la même chose que 4
 
chrisbk : si seulement...
 
il faut que je donne tableau des valeurs et arguments, plus définition, plus faire un programme d'exemple pour strcpy, strcat, strncat, strcmp, strncmp, strrev, strset, strstt...  
 
Je n'ai d'exemple imposé que pour strpbrk, pour les autres, je peux inventer ce qui me branche alors ça va.

Reply

Marsh Posté le 27-11-2003 à 22:32:03    

pourquoi ce programme pourrait-il planter ?
(hint : pointeur, NULL)
 
est ce que  

Code :
  1. p=strpbrk(p,voyelles);


 
peut te renvoyer un pointeur sur le caractère de fin de chaîne '\0' alors qu'il ne fait pas partie des caractères que tu recherches ?
 
 
Quand est ce que  

Code :
  1. p=strpbrk(p,voyelles);


te retourne NULL ?

Reply

Marsh Posté le 27-11-2003 à 22:47:24    

putain je me barre une soirée et c'est le bordel ! et les std::string, et std::string::find_first_of, etc :o

Reply

Marsh Posté le 27-11-2003 à 22:48:19    

Taz a écrit :

putain je me barre une soirée et c'est le bordel ! et les std::string, et std::string::find_first_of, etc :o


 
void main(void) :ange:  
 

Reply

Marsh Posté le 27-11-2003 à 22:48:19   

Reply

Marsh Posté le 27-11-2003 à 22:54:05    

Ah ouais OK, s'il ne regarde pas fin de chaine, je fais un  
while (i<strlen(chaine))  
{
i++;
...
}
 
Je peux rencontrer un NULL quand il n'y a pas/plus de correspondance, mais est qu'un NULL peut faire planter le pg ?

Reply

Marsh Posté le 27-11-2003 à 22:58:47    

Taz a écrit :

putain je me barre une soirée et c'est le bordel ! et les std::string, et std::string::find_first_of, etc :o


 
 :heink:  
 
J'ai pas encore appris à me servir de ça. :/  
 
Je pense pas que ça soit vital pour mon programme.

Reply

Marsh Posté le 27-11-2003 à 22:59:42    

Master_Jul a écrit :

Ah ouais OK, s'il ne regarde pas fin de chaine, je fais un  
while (i<strlen(chaine))  
{
i++;
...
}


ce qui marchera uniquement si toutes les lettes de ta chaine sont des voyelles.
 
 

Master_Jul a écrit :


Je peux rencontrer un NULL quand il n'y a pas/plus de correspondance, mais est qu'un NULL peut faire planter le pg ?  


un NULL ne fait pas planter un programme, déréférencer un pointeur nul, si.
 
et si il n'y a plus de correspondance, ca ne voudrait pas dire par un hazard improbable qu'il ne reste plus de voyelles dans ta chaine ?

Reply

Marsh Posté le 27-11-2003 à 23:07:06    

Je ne comprend pas le "déférencement de pointeur"
 
On écrit ça comme ça ?
 
 while (*p!='NULL')
 {
  p=strpbrk(p,voyelles);
  cout <<p<<endl;
  p++;
  xvoy++;
 }
 
ou
 
 while (p!='NULL')

Reply

Marsh Posté le 27-11-2003 à 23:13:28    

Master_Jul a écrit :

Je ne comprend pas le "déférencement de pointeur"
 
On écrit ça comme ça ?
 
 while (*p!='NULL')
 {
  p=strpbrk(p,voyelles);
  cout <<p<<endl;
  p++;
  xvoy++;
 }
 
ou
 
 while (p!='NULL')


 
 [:albator7k]  :pfff:  
 
déréférencement de pointeur =>  

Code :
  1. char *p;
  2. *p; /* ca c'est un déréférencement de pointeur


 
Y a de l'idée dans la première solution sauf qu'elle compile pas, c'est pas comme ca qu'on teste un pointeur nul, mais alors pas du tout.
et en plus ca marcherait pas même si ca compilait.
 
test de pointeur :

Code :
  1. char *p;
  2. p = NULL;
  3. if(p == NULL)
  4. {
  5.   /* le pointeur est nul */
  6. }
  7. if(!p)
  8. {
  9.   /* le pointeur est nul */
  10. }


 
(PS : c'est un troll ou quoi ?)

Reply

Marsh Posté le 27-11-2003 à 23:20:40    

Je suis conscient d'être un gros boulet mais j'ai vraiment du mal sur ce coup. :/
 
Je change d'idée, mais je sens que ça devient de plus en plus con, je fais une boucle infinie que je casse quand je rencontre un NULL suivant la syntaxe que tu m'as donné :
 

Code :
  1. char *p;
  2. p=strpbrk(szPhrase,voyelles);
  3. while (1)
  4. {
  5.  p=strpbrk(p,voyelles);
  6.  cout <<p<<endl;
  7.  if (p == NULL) return(xvoy);
  8.  p++;
  9.  xvoy++;
  10. }


 
Maintenant je vois pas le problème avec le pointeur, quand je fais un :
 
p=strpbrk(p,voyelles);
Ca veut dire que je stocke un pointeur dans p qui en est déjà un... ah c'est peut être ça le hic.

Reply

Marsh Posté le 27-11-2003 à 23:25:49    

Je trouve pas, faut que je rende ce truc avant minuit :'(.

Reply

Marsh Posté le 27-11-2003 à 23:27:23    

bon si c'est un devoir => pas de commentaires => 0/20.
                       => return dans un while(1) => 0/20.
 
pourquoi ta première solution n'aurait pas marché :
 

Code :
  1. p=strpbrk(szPhrase,voyelles);
  2. while (p != NULL) /*c*/
  3. {
  4.   p=strpbrk(p,voyelles); /*a*/
  5.   cout <<p<<endl;
  6.   p++; /*b*/
  7.   xvoy++;
  8. }


 
a la fin de la recherche, en /*a*/ on se retrouve avec un pointeur nul, super.
en /*b*/, pas de bol on ajoute 1 au pointeur.
donc en /*c*/ le test foire parce que que le pointeur ne vaut pas nul.
 
une solution qui marche [edit ou qui devrait marcher ;)]:

Code :
  1. p=strpbrk(szPhrase,voyelles);
  2. while (p != NULL) /*c*/
  3. {
  4.   cout <<p<<endl;
  5.   p++; /*b*/
  6.   p=strpbrk(p,voyelles); /*a*/
  7.   xvoy++;
  8. }


 
[edit]viré le commentaire, dis moi pourquoi ca devrait marcher.


Message édité par SquiZZ le 27-11-2003 à 23:32:01
Reply

Marsh Posté le 27-11-2003 à 23:35:02    

A tout hasard (j'avoue), j'avais essayé de mettre le p++; avant de tester mais ça devait pas être au moment où je testais la bonne chose (cf. le !='\0') :/
 
En tout cas, j'ai compris mes erreurs, merci pour toutes tes explications, je promet de me creuser un peu plus la tête la prochaine fois. Je devrai utiliser un peu plus le debugger en pas à pas à mon avi.
 
Encore merci !
 
Edit : J'ai vu avant l'edit  [:cupra] mais j'aurai compris, j'ai déjà rencontré ce genre de bourde avec les chaines quand on récupèrait la longueur de celle-ci "à la main" en recherchant le terminator.


Message édité par Master_Jul le 27-11-2003 à 23:37:32
Reply

Marsh Posté le 27-11-2003 à 23:45:00    

quelqu'un pour déplacer ça dans la cat C ?

Reply

Marsh Posté le 27-11-2003 à 23:47:46    

Taz a écrit :

quelqu'un pour déplacer ça dans la cat C ?


tiens j'avais pas fait gaffe à la cat.
Quoi que c'est a moitié du C++, y a des 'cout'  [:ddr555]

Reply

Marsh Posté le 27-11-2003 à 23:49:30    

SquiZz a écrit :

Quoi que c'est a moitié du C++, y a des 'cout'  [:ddr555]  

:pfff:

Reply

Marsh Posté le 28-11-2003 à 00:09:23    

SquiZz a écrit :


tiens j'avais pas fait gaffe à la cat.
Quoi que c'est a moitié du C++, y a des 'cout'  [:ddr555]  


J'ai deplacé parce que sinon le Taz nous faisait une attaque d'apoplexie :D
Z'etes dur avec lui de poster ca dans la cat C++, alors que c'est du C plusplus-isant.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-11-2003 à 00:16:52    

Bon sinon, pour M_J, j'explicite ma remarque:

Code :
  1. ......
  2.     p=strpbrk(szPhrase,voyelles);
  3.    
  4.      while (*p!='\0')
  5. ..........


Si tu n'as pas de voyelle dans szPhrase p sera mis a NUL. Or ton test se fait sur *p  :non:  :non:  :non:  
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-11-2003 à 00:45:04    

Tiens, un exemple de solution en pur C  
Reecris donc ca ensuite en vrai C++ pour faire plaisir a Taz
J'ai modifie certains de tes identificateurs pour les mettre plus conformes aux habitudes du code C
Au fait, main est pas du prototype que tu avait mis, meme si ton compilo l'accepte
 

Code :
  1. #include <string.h>
  2. #include <stdio.h>
  3. int compteVoyelles (char *szPhrase)
  4. {
  5. int compteur = 0;
  6. // si pas de chaine ou chaine vide, on a pas besoin de compter
  7. if (szPhrase && *szPhrase)
  8. {
  9.  char voyelles[] = "aeiouyAEIOUY";
  10.      char *p = szPhrase;
  11.  while (p = strpbrk(p, voyelles))
  12.  {
  13.   // printf("%s\n", p); // mis ton test de debug en commentaires
  14.   compteur++;
  15.   p++;
  16.  }
  17. }
  18. return(compteur);
  19. }
  20. int main(int argc, char *argv[])
  21. {
  22. char chaine[] = "Il me semble qu il pleut dehors.";
  23.     int  nbVoyelles;
  24. nbVoyelles = compteVoyelles(chaine);
  25. printf("La chaine est : %s\n", chaine);
  26. printf("Le nombre de voyelles est : %d\n", nbVoyelles);
  27. return 0;
  28. }


 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-11-2003 à 01:17:16    

pour ceux qui veulent je faire en C++, plusieurs solutions simples :
- une boucle avec std::string::find_first_of
- std::count_if + ce_qu'_il_faut

Reply

Marsh Posté le 28-11-2003 à 04:58:20    

j'ai bon ?
 

Code :
  1. #include <string>
  2. #include <algorithm>
  3. using namespace std;
  4. string Voyelles = "aeiouyAEIOUY";
  5. bool Bordel(char c)
  6. {
  7. return (Voyelles.find(c) != string::npos);
  8. }
  9. int main()
  10. {
  11. string str = "Dans ton cul, konar !";
  12. size_t count = count_if(str.begin(), str.end(), Bordel);
  13. return 1;
  14. }

Reply

Marsh Posté le 28-11-2003 à 08:57:38    

oui sauf la variable globale (de visibilité externe qui plus est) qui est très laide. et quand on peut le faire, on utilise le constructeur avec argument et pas l'initialisation par copie. quelque parenthèse en trop


Message édité par Taz le 28-11-2003 à 08:57:59
Reply

Marsh Posté le 28-11-2003 à 13:01:44    

ouais la globale j'en étais pas très fier, et pour les parenthèses c'était une norme de mon ancien bahut de merde, qui disait qu'il fallait en mettre après chaque mot clé (for, sizeof, if, return, etc).
 
sinon ok pour le constructeur, j'y pense jamais mais faudrait.
 
et tout compte fait cette solution me semble mieux :
(enfin plus simple, et y a pas une fonction Bordel() qui traine)
 

Code :
  1. size_t Count(const string &str)
  2. {
  3. size_t res = 0;
  4. string Voyelles("aeiouyAEIOUY" );
  5. for (string::const_iterator i = str.begin(); i != str.end(); i++)
  6.  if (Voyelles.find(*i) != string::npos)
  7.   res++;
  8. return res;
  9. }

Reply

Marsh Posté le 28-11-2003 à 13:30:38    

Et les voyelles accentuées, faut les compter aussi ? :o


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 28-11-2003 à 13:35:19    

antp a écrit :

Et les voyelles accentuées, faut les compter aussi ? :o


 
ben øüì, cä me påräìt evídent

Reply

Marsh Posté le 28-11-2003 à 13:48:03    

Y a des cas sympathiques [:figti] par ex en néerlandais "ij" peut s'écrire "ÿ", ça fait une voyelle + une consonne :D


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 28-11-2003 à 20:29:39    

quelqu'un pour déplacer ça dans la cat C++ ? (spéciale dédicace à Taz  [:ddr555]^2

Reply

Marsh Posté le 29-09-2009 à 18:12:38    

Salut, moi aussi je dois faire un compteur de voyelle dans une phrase se terminant par *
Voila deja ce que j'ai fais.
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5.   char phrase[100];
  6.   int c = 0;    // Compteur de voyelle
  7.   int d = 0; 
  8.  
  9.   printf("Rentrez une phrase se terminant par *\n\n" );
  10.   scanf("%s", &phrase);
  11.  
  12.   while ( phrase[d] != '*' )
  13.    {
  14.         if ( phrase[d] == 'a' || phrase[d] == 'e' || phrase[d] == 'i' || phrase[d] == 'o' || phrase[d] == 'u' || phrase[d] == 'y' )
  15.           {
  16.                     c++; // Incrementation du compteur de voyelles
  17.                     d++; // Incrementation du tableu
  18.           }
  19.         else
  20.           { d++; }
  21.    }
  22.  
  23.  
  24.   printf("Il y a %i voyelles dans votre phrase !\n", c);
  25.   system("PAUSE" );
  26.   return 0;
  27. }


 
Voila , sa marche parfaitement si je colle tout mais des que je met des espaces dans ma phrase sa m'affiche un nombre de voyelle erronés pourquoi cela ? Merci de vos explication !

Reply

Marsh Posté le 29-09-2009 à 21:36:18    

Renseigne toi sur l'utiliisation du scanf !
La saisie des chaines au clavier se fait avec fgets(buf, sizeof buf, stdin).

Reply

Marsh Posté le 30-09-2009 à 23:25:32    

keek007 a écrit :


Voila deja ce que j'ai fais.
 

Code :
  1. ...
  2.   char phrase[100];
  3. ...
  4.   scanf("%s", &phrase);
  5. ...
  6. if (...)
  7. {
  8.      ...
  9.      d++;
  10. }
  11. else
  12. { d++; }


 
Voila , sa marche parfaitement


Supaire !!! :sarcastic:


Message édité par Sve@r le 30-09-2009 à 23:26:17

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 01-10-2009 à 02:09:16    

Salut les bizus de tek1
J'ai pas regardé si la réponse a été postée, trop de flood.
 
en C pur et dur sans fonction de la bibli pour compter le nombre de voyelles d'une phrase on a : (a la norme en plus !)
 

Code :
  1. int compteur(char *str)
  2. {
  3. char *voyelle;
  4. int compteur;
  5. int i;
  6.  
  7. compteur = 0;
  8. voyelle = "aeiouyAEIOUY";
  9. while (*str != '\0')
  10. {
  11.  i = 0;
  12.  while (voyelle[i] != '\0')
  13.   if (voyelle[i++] == *str)
  14.    compteur++;
  15.  str++;
  16. }
  17. return (compteur);
  18. }


Voilou


Message édité par licaprout le 01-10-2009 à 02:10:15
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed