Compter le nombre de mots dans une CString.

Compter le nombre de mots dans une CString. - C++ - Programmation

Marsh Posté le 23-11-2004 à 19:21:29    

Bonjour, j'aurai besoin de deux petits applications sur des CString, je créé une classe CPhrase qui hérite la première pour "l'améliorer" et lui ajouter quelques méthodes :
 

int GetNbMots();               // Récupérer le nombre de mots dans la CString
void Supprime(CString strMot); // Supprimer le mot de la CString
void Supprime(CString *szMot);


 
J'étais parti avec l'idée de faire un algo assez basique que j'utilisais en C avec les chaines de caractères du type :
 

Index = Position dans la chaine
 
Pour chaque caractère de la chaine
   Si c'est un espace,
      Incrémenter l'Index
   Sinon
      Incrémenter NbMot
      Incrémenter l'Index
      Tant que le caractère n'est pas un espace
         Incrémenter l'Index
      Fin tant que
   Fin si
Fin pour


 
En pratique, je n'arrive pas à utiliser la méthode Find de la classe CString correctement, j'arrive pour le moment à repérer l'emplacement des espaces mais j'aimerai bien appliquer l'idée de mon algorithme, pourriez-vous me conseiller ?
 
Voilà le peu de code actuel :
 

Code :
  1. void main()
  2. {
  3. CPhrase MaPhrase("salut   c'est moi" );
  4. cout<<MaPhrase;
  5. cout<<MaPhrase.GetNbMots();
  6. }


 

Code :
  1. int CPhrase::GetNbMots()
  2. {
  3. int i,index;
  4. int NbMots=0;
  5. bool NewMot=false;
  6. for(i=0;i<CPhrase::GetLength();i++)
  7. {
  8.  // Affiche l'emplacement des espaces dans la chaine
  9.         index=CPhrase::Find(' ',i);
  10.  if(index>0)
  11.  {
  12.   cout << " Espace :"<<index<<"\n";
  13.   i=index;
  14.  }
  15.  else
  16.   return 0;
  17. }
  18. return NbMots;
  19. }


Message édité par Master_Jul le 23-11-2004 à 19:22:37
Reply

Marsh Posté le 23-11-2004 à 19:21:29   

Reply

Marsh Posté le 23-11-2004 à 19:30:10    

le nombre de mots d'une phrase (bien formée) est habituellement égal au nombre de blancs +1 (sachant qu'un blanc est censé faire un espace, mais il peut faire plus)
 
(habituellement parce que certains signes de ponctuation ont des règles spéciales)
 
Donc récupères la position du prochain espace puis fait un poll sur les 2 caractères adjacents, si t'as un espace tu recommences en te décalant (histoire d'arriver au mot suivant en prenant tous les espaces comme un blanc unique) sinon vérifie si c'est pas un signe de ponctuation avec des règles bizarres.


Message édité par masklinn le 23-11-2004 à 19:32:23

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 23-11-2004 à 19:32:39    

Oui, en théorie, mais là je dois pouvoir gérer un nombre inconnu d'espaces entre les mots ainsi que des espaces en début et fin de chaine s'il y en a.
 
Edit pour ton edit ;) :
 
C'est bien ce que j'ai tenté de faire mais Find renvoit l'emplacement de la prochaine occurence, moi j'aimerai connaître/comparer mon ' ' avec un caractère x de la chaine, ça serait beaucoup plus simple.


Message édité par Master_Jul le 23-11-2004 à 19:34:46
Reply

Marsh Posté le 23-11-2004 à 19:33:08    

Master_Jul a écrit :

Oui, en théorie, mais là je dois pouvoir gérer un nombre inconnu d'espaces entre les mots ainsi que des espaces en début et fin de chaine s'il y en a.


j'ai édité


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 23-11-2004 à 19:33:17    

si la phrase est bien formée :/
 
moi je ferais la technique classique du wc : une variable pour compter les mots et un booléen 'inside_word'. Tu parcours ta chaine char par char, à chaque fois que 'inside_word' passe de false à true, tu comptes un mot de plus.
 
isspace est ton amie

Reply

Marsh Posté le 23-11-2004 à 19:36:00    

Taz a écrit :

un booléen 'inside_word'. Tu parcours ta chaine char par char, à chaque fois que 'inside_word' passe de false à true, tu comptes un mot de plus.


Ouaip, mais comment tu décites qu'un caractère fait partie d'un mot?


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 23-11-2004 à 19:59:54    

isspace

Reply

Marsh Posté le 23-11-2004 à 20:06:26    

Oui, je veux bien utiliser isspace mais comment fais-je pour parcourir mon objet CPhrase caractère par caractère ? Avec une char[] ok mais là ? Je ne vais pas caster mon objet en char pour compter les mots quand même, ça fait un peu barbare.

Reply

Marsh Posté le 23-11-2004 à 20:32:43    

Master_Jul a écrit :

Oui, je veux bien utiliser isspace mais comment fais-je pour parcourir mon objet CPhrase caractère par caractère ? Avec une char[] ok mais là ? Je ne vais pas caster mon objet en char pour compter les mots quand même, ça fait un peu barbare.


 
ben dans la classe CString t as pas une methode genre getCharAt(position) ?
sinon ben tu convertis en char * avec un getBuffer() hein (au pire...)


Message édité par PtitKiki le 23-11-2004 à 20:34:41
Reply

Marsh Posté le 23-11-2004 à 20:36:51    

PtitKiki a écrit :

ben dans la classe CString t as pas une methode genre getCharAt(position) ?
sinon ben tu convertis en char * avec un getBuffer() hein.


 
Ben non, sinon je n'aurai pas fait ce topic. J'aimerai pouvoir le faire en  ne touchant pas à mon objet, il doit bien y avoir une manière d'utiliser les méthodes de CString pour faire ça.
 
http://msdn.microsoft.com/library/ [...] string.asp
 
Edit : Je suis con, je viens de tomber sur Getat, il n'est pas dans ma doc CD apparemment mais il est sur le net...


Message édité par Master_Jul le 23-11-2004 à 20:41:20
Reply

Marsh Posté le 23-11-2004 à 20:36:51   

Reply

Marsh Posté le 23-11-2004 à 20:39:51    

Reply

Marsh Posté le 23-11-2004 à 20:39:57    

Je ne connais pas les CString, mais tu dois pouvoir récupérer un const char* j'imagine. Pourquoi pas comme çà ? Ca a le mérite d'entre assez compact :)
 

Code :
  1. {
  2. std::istringstream ext( mastring )
  3. std::string s ;
  4. unsigned int cpt = 0 ;
  5. while(ext >> s) ++cpt ;
  6. ...
  7. }


Reply

Marsh Posté le 23-11-2004 à 20:43:05    

Evadream -jbd- a écrit :

tu dois pouvoir récupérer un const char* j'imagine.  


Oui, tu récupéres un LPCTSTR, qu'il faut ensuite convertir en const char * (via unicode->Ansi si nécessaire).

Reply

Marsh Posté le 23-11-2004 à 20:46:59    

Lam's a écrit :

...LPCTSTR...


 
:hebe: Ca paraît pas très docile cette bête :)

Reply

Marsh Posté le 23-11-2004 à 20:49:57    


 
C'est bien ce que j'ai tenté :
 
cout<<CPhrase[0];
 
Mais le compilateur dit :
CPhrase.cpp(38): error C2275: 'CPhrase' : utilisation non conforme de ce type comme expression
 
Par contre, cout<<CPhrase::GetAt(0) marche bien ! Je vais donc pouvoir continuer mon programme comme je l'avais prévu. Merci à tout le monde !

Reply

Marsh Posté le 23-11-2004 à 20:50:36    

Evadream -jbd- a écrit :

:hebe: Ca paraît pas très docile cette bête :)


C'est un const char * ou un const wchar *, suivant que tu compiles en mode unicode ou pas. Perso, j'adore ! :love:

Reply

Marsh Posté le 23-11-2004 à 20:51:56    

Master_Jul a écrit :

C'est bien ce que j'ai tenté :
 
cout<<CPhrase[0];
 
Mais le compilateur dit :
CPhrase.cpp(38): error C2275: 'CPhrase' : utilisation non conforme de ce type comme expression


 
C'est parce que l'opérateur [] n'est pas défini dans ta classe CPhrase. Il n'est défini que dans CString. De toutes façons, je te déconseille très fortement d'hériter de CString pour ce genre de choses...
 

Reply

Marsh Posté le 23-11-2004 à 21:08:15    

Lam's a écrit :

C'est un const char * ou un const wchar *, suivant que tu compiles en mode unicode ou pas. Perso, j'adore ! :love:


 
Ok, merci pour la précision ! @+

Reply

Marsh Posté le 23-11-2004 à 21:09:57    

Lam's a écrit :

C'est parce que l'opérateur [] n'est pas défini dans ta classe CPhrase. Il n'est défini que dans CString. De toutes façons, je te déconseille très fortement d'hériter de CString pour ce genre de choses...


 
Ok merci, voilà mon code, il a l'air de fonctionner correctement (on considère des caractères seuls, la ponctuation comme des mots...) :
 

Code :
  1. int CPhrase::GetNbMots()
  2. {
  3. int i,taille;
  4. int NbMots=0;
  5. taille=CPhrase::GetLength();
  6. for(i=0;i<taille;i++)
  7.  if(!isspace(CPhrase::GetAt(i)))
  8.  {
  9.   NbMots++;
  10.   while(!isspace(CPhrase::GetAt(i)) && i<taille)
  11.    i++;
  12.  }
  13. return NbMots;
  14. }


 
 :hello:

Reply

Marsh Posté le 23-11-2004 à 21:11:32    

Evadream -jbd- a écrit :

Ok, merci pour la précision ! @+


En fait, je voulais juste attirer l'attention sur le fait que de nos jours, un programme décent (surtout sous Windows) se devait de considérer l'utilisation d'Unicode. Surtout qu'il existe plein de code disponible pour simplifier tout ça (bon, pas forcément des LPCTSTR, mais tu vois le genre).  
 
Et les MFC permettent ça assez facilement. C'est sans doute l'un des seuls avantages de cette librairie.

Reply

Sujets relatifs:

Leave a Replay

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