Decomposition chaine de caractère

Decomposition chaine de caractère - C++ - Programmation

Marsh Posté le 10-10-2015 à 22:06:09    

Bonsoir,
 
un de mes exercices est de faire rentrer une phrase à l'utilisateur, et découper chaque moi de cette même phrase.
Le programme doit ensuite être capable de trouver le mot le plus longt.
Je ne sais vraiment pas si ce que j'ai fais s'approche de ce qui est demandé, ou alors si je suis completement à coter de la plaque mais mon code
ne fonctionne pas encore:
 

Code :
  1. #include <iostream>
  2. #include <conio.h>
  3. using namespace std;
  4. void main()
  5. {
  6. const int Nmax = 1000;
  7. char tab[Nmax];
  8. int mot;
  9. int memoire=0;
  10. char tab2[Nmax];
  11. char c='-';
  12. int f = 0;
  13. int compteur=1;
  14. cout << "Bonjour, veuillez ecrire votre phrase : " << endl;
  15. while (c != '.') // tant que c ne retourne pas un point, la boucle tourne {  
  16.  while (c != ' ')
  17.  { 
  18.   c = _getche(); // affectation d'une lettre à c
  19.   tab[f] = c; // place le mot dans tab
  20.   f++; // f prend la valeur f+1
  21.   compteur++;
  22.  }
  23.  mot = strlen(tab); //enregistre le nombre de caractère du mot
  24.  if (mot > memoire) //compare tour a nombre la longueur des mots
  25.  {
  26.   memoire = mot;
  27.   for (int i = 0; i < compteur; i++)
  28.   {
  29.    tab2[i] = tab[i]; // affecte la valeur de tab dans tab2
  30.   }
  31.  }
  32.  else
  33.  {
  34.   if (mot <= memoire)
  35.   {
  36.    memoire = memoire;
  37.   }
  38.  }
  39. }
  40. cout << "le mot le plus longt est :\n";
  41. for (int i = 0; i < compteur; i++)
  42. {
  43.  std::cout << tab2[i];
  44. }
  45. _getch();
  46. }


 
Ps : je suis pas très fort en programmation, j'espère que mon code à quand même du sens. pour des propositions éventuelles d'utiliser des String, on a pas le droit dans cet exercice.
 
Cordialement

Reply

Marsh Posté le 10-10-2015 à 22:06:09   

Reply

Marsh Posté le 11-10-2015 à 10:53:09    

Déjà rien qu'avec un éditeur de texte à coloration syntaxique, on voit le premier bug:
while (c != '.') // tant que c ne retourne pas un point, la boucle tourne {  
 
 
et ça  
void main()
c'est guère mieux.
 
Enfin
#include <conio.h>
vaut mieux éviter pour du code portable basique.
 
A+,


Message édité par gilou le 11-10-2015 à 11:22:55

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

Marsh Posté le 11-10-2015 à 11:21:11    

D'autre part, ce code ressemble à du C, pas du C++.
Si tu manipules des chaînes de caractères, std::string est fait pour cela, inutile de passer par des tableaux de chars.
 
Regardes donc ce qui se passe quand tu fais  
std::string mot;
cin >> mot;
et extrapoles ce que tu peux faire avec  
while (cin >> mot) {
...
}
 
et quand tu auras testé et que tu auras vu la limitation de cette méthode due au comportement de cin avec la fin de ligne (il bouffe la fin de ligne et reste en attente d'un mot), tu pourras passer à la méthode standard:

Code :
  1. std::string input;
  2. std::getline(std::cin, input);
  3. std::istringstream ligne(input);
  4.    
  5. std::string mot;
  6. while (ligne >> mot) {
  7.     ....
  8.     }
  9. }


 
A+,


Message édité par gilou le 11-10-2015 à 12:30:47

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

Marsh Posté le 11-10-2015 à 12:31:53    

Merci de ta réponse, je sais que String est plus simple, cependant les profs veulent qu'on manipule les tableaux de char... C'est également eux qui nous demandent d'importer <conio.h>

Reply

Marsh Posté le 11-10-2015 à 16:40:09    

Donc les profs en question n'ont jamais appris correctement le C++, en sont restés à des manières de programmer datant d'il y a 20 quand ils ont appris le C, et ils vous rendent un très mauvais service en ne vous enseignant pas les bonnes méthodes.
 

Code :
  1. #include <iostream>
  2. #include <sstream>
  3. #include <string>
  4. int main() {
  5.     std::string mot_maxi = "";
  6.    
  7.     std::cout << "Bonjour, veuillez ecrire votre phrase : " << std::endl;
  8.     std::string input;
  9.     std::getline(std::cin, input);
  10.     std::istringstream ligne(input);
  11.    
  12.     std::string mot;
  13.     while (ligne >> mot) {
  14.         if (mot.size() > mot_maxi.size()) {
  15.             mot_maxi = mot;
  16.         }
  17.     }
  18.    
  19.     if (mot_maxi.size() > 0) {
  20.         std::cout << "Le mot le plus longt est : " << mot_maxi << std::endl;
  21.     }
  22.     else {
  23.         std::cout << "La phrase n'a pas de mots!" << std::endl;
  24.     }
  25.    
  26.     return 0;
  27. }


 
Bon, après, on peut vraiment utiliser les possibilités du C++ pour faire quelque chose de flexible et efficace:

Code :
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <iterator>
  4. #include <sstream>
  5. #include <string>
  6. #include <vector>
  7. int main() {
  8.     // on récupére l'input dans une ligne
  9.     std::cout << "Bonjour, veuillez ecrire votre phrase : " << std::endl;
  10.     std::string input;
  11.     std::getline(std::cin, input);
  12.     // on parse la ligne pour obtenir un vecteur de mots
  13.     std::istringstream ligne(input);
  14.     std::vector<std::string> mots;
  15.     std::copy(std::istream_iterator<std::string>(ligne), std::istream_iterator<std::string>(), std::back_inserter(mots));
  16.     // s'il n'y a pas de mots, on sort
  17.     if (mots.size() == 0) {
  18.         std::cout << "Il n'y a aucun mot!" << std::endl;
  19.         return 1;
  20.     }
  21.     // on vire les mots dupliqués
  22.     std::sort(mots.begin(), mots.end());
  23.     mots.erase(std::unique(mots.begin(), mots.end()), mots.end());
  24.     // on trouve la taille maximale
  25.     int maxsize = std::max_element(mots.begin(), mots.end(), [](std::string a, std::string b) {return (a.size() < b.size());})->size();
  26.     // on vire les mots de taille non maximale
  27.     mots.erase(std::remove_if(mots.begin(), mots.end(), [maxsize](std::string a) {return (a.size() != maxsize);}), mots.end());
  28.     // on liste les mots restant
  29.     if (mots.size() == 1) {
  30.         std::cout << "\nLe mot de taille maximale est: " << mots.at(0) << std::endl;
  31.     }
  32.     else {
  33.         std::cout << "\nLes mots de taille maximale sont: " ;
  34.         std::copy(mots.begin(), mots.end(), std::ostream_iterator<std::string>(std::cout, " " ));
  35.         std::cout << std::endl;
  36.     }
  37.     return 0;
  38. }


Manque juste le code pour imprimer les mots séparés par une virgule, quand il y en a plusieurs, mais ça me semble pas utile de le mettre ici.
 
A+,

Message cité 1 fois
Message édité par gilou le 11-10-2015 à 19:06:38

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

Marsh Posté le 11-10-2015 à 21:24:23    

Bah merci beaucoup, j'espere que je vais pas me faire engueuler x)
J'avais appris tout sa en Java (son equivalence) dans un autre etablissement et c'etait plus facile avec les String je suis d'accord. Mais dans ce nouveau batiment avec leurs C++, ils veulent pas encore nous présenter les String et je me demande pourquoi ^^^
 
Merci pour ton code Gilou :) :bounce:

Reply

Marsh Posté le 13-10-2015 à 14:02:28    

gilou a écrit :

Manque juste le code pour imprimer les mots séparés par une virgule, quand il y en a plusieurs, mais ça me semble pas utile de le mettre ici.

En y réfléchissant un peu, c'est tout bête:

Code :
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <iterator>
  4. #include <locale>
  5. #include <sstream>
  6. #include <string>
  7. #include <vector>
  8. int main() {
  9.     // on récupére l'input dans une ligne
  10.     std::cout << "Bonjour, veuillez ecrire votre phrase : " << std::flush;
  11.     std::string input;
  12.     std::getline(std::cin, input);
  13.     // On vire la ponctuation sauf le - pour les mots composés
  14.     std::replace_if(input.begin(), input.end(), [](char c) {return (std::ispunct(c) && (c != '-'));}, ' ');
  15.     // on parse la ligne pour obtenir un vecteur de mots
  16.     std::istringstream ligne(input);
  17.     std::vector<std::string> mots;
  18.     std::copy(std::istream_iterator<std::string>(ligne), std::istream_iterator<std::string>(), std::back_inserter(mots));
  19.     // s'il n'y a pas de mots, on sort
  20.     if (mots.size() == 0) {
  21.         std::cout << "Il n'y a aucun mot!" << std::endl;
  22.         return 1;
  23.     }
  24.     // on vire les mots dupliqués
  25.     std::sort(mots.begin(), mots.end());
  26.     mots.erase(std::unique(mots.begin(), mots.end()), mots.end());
  27.     // on trouve la taille maximale
  28.     int maxsize = 0;
  29.     std::for_each(mots.begin(), mots.end(), [&maxsize](std::string a) {if (a.size() > maxsize) maxsize = a.size();});
  30.     // on vire les mots de taille non maximale
  31.     mots.erase(std::remove_if(mots.begin(), mots.end(), [maxsize](std::string a) {return (a.size() != maxsize);}), mots.end());
  32.     // on liste les mots restant
  33.     if (mots.size() == 1) {
  34.         std::cout << "\nLe mot de taille maximale est: " << mots.at(0) << '.' << std::endl;
  35.     }
  36.     else {
  37.         std::cout << "\nLes mots de taille maximale sont: " ;
  38.         std::copy(mots.begin(), mots.end()-1, std::ostream_iterator<std::string>(std::cout, ", " ));
  39.         std::cout << mots.back() << '.' << std::endl;
  40.     }
  41.     return 0;
  42. }


 
A+,


Message édité par gilou le 13-10-2015 à 14:39:29

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

Sujets relatifs:

Leave a Replay

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