IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Nombre de voyelles contenues dans une chaine de caractères (C++)


Sujet :

C++

  1. #1
    Membre averti
    Homme Profil pro
    Etudiant en Mthématique et informatique
    Inscrit en
    Octobre 2014
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Algérie

    Informations professionnelles :
    Activité : Etudiant en Mthématique et informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Octobre 2014
    Messages : 15
    Par défaut Nombre de voyelles contenues dans une chaine de caractères (C++)
    Salut !
    Je doit faire une fonction qui renvoie le nombre de voyelles contenues dans une chaine de caractères passée en argument, sachant que je cherche la solution la plus simple (je suis vraiment un débutant !) et entièrement en C++.
    Je me suis dit qu'il fallait décomposer la chaine de caractères en caractères que je pourrais mettre dans un tableau de caractères (ça fait beaucoup de caractères :S !), mais je voie pas comment ?!
    Voici ce que j'ai pu faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    #include<iostream>
    using namespace std;
     
    int nombreVoyelles(string cc)
    { 
    	// J'aimerai décomposer la chaine de caractères en caractères :
    	// char tc[] = "C'est facile !"; <--- Ici ça marche très bien, aucun problème !
    	char tc[1000] = cc; // Mais là, ça ne marche pas :( ! Pourtant, c'est une variable de type "string" ! 
     
    	int nv=0;
    	for(int i=0; tc[i]!='\0' /*  ou "i<cc.size()"  */; i++ /*  ou "++i" ? Quelle différence ? :p  */)
    	{
    		if(((tc[i]=='a') || (tc[i]=='e') || (tc[i]=='i') || (tc[i]=='o') || (tc[i]=='u') || (tc[i]=='y'))  ||  ((tc[i]=='A') || (tc[i]=='E') || (tc[i]=='I') || (tc[i]=='O') || (tc[i]=='U') || (tc[i]=='Y')))
    		{
    			nv++;
    		}
    	}
    	return nv;
    }
     
    int main()
    {
    	cout<<"\n         - Nombre de voyelles contenues dans une chaine de caract\212res -\n\n";
     
    	string chaine;
    	cout<<"\n Saisissez votre chaine de caract\212re :\n "; cin>>chaine;
     
    	int nbVoyelles;
    	nbVoyelles = nombreVoyelles(chaine);
     
    	cout<<"\n\n Votre chaine de caract\212res contient "<<nbVoyelles<<" voyelles !";
     
    	cout<<"\n\n\n	";
    	system("pause");
            return 0;
    }

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 746
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 746
    Par défaut
    string est un objet ... avec des méthodes dedans

    std::string::c_str (*)
    std::string::length

    Et si tu es assez avancé :
    std::string::begin
    std::string::end

    Toutes les méthodes sur cette page


    * -> il y a aussi la méthode data, mais en fonction de ton compilateur soit elle équivalente à la méthode c_str soit elle n'est pas terminée par le caractère '\0'

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 144
    Billets dans le blog
    4
    Par défaut
    Entierement en C++ moderne ? Parce que tes char tc[] = "C'est facile !"; sont du bon gros C hein.
    Quelaue chose comme ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    int compterVoyelles(const std::string& s)
    {
      return std::count_if(s.begin(), s.end(), [](char c) {
        switch(c) {
          case 'a':
          case 'A':
          case 'e':
          case 'E':
          case 'i':
          case 'I':
          case 'o':
          case 'O':
          case 'u':
          case 'U':
          case 'y':
          case 'Y':
            return true;
          default:
            return false;
        }
      });
    }
    a vue de nez
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Membre Expert
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Par défaut
    Je propose une alternative, std::count_if. Il s'agit d'une fonction comptant le nombre d'éléments contenus dans un container qui vérifie une prédicat. ici, tu veux compter le nombre de caractères dans une string qui sont des voyelles.

    Afin de t'orienter (car la définition formelle de la fonction std::count_if peut paraître mystique quand on débute), voici un exemple, dans un std::vector d'entiers, je vais compter les nombres impaires.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <vector>
    #include <algorithm>
    #include <iostream>
     
    bool isOdd(int n)
    {
        return n % 2 != 0;
    }
     
    int main()
    {
        const std::vector<int> data{0,2,8,3,41,-86,35,10,86,99,100};
        const std::size_t countOfOddNumbers = std::count_if(data.begin(), data.end(), isOdd);
     
        std::cout << "Number of odd numbers: " << countOfOddNumbers  << "." << std::endl;
    }
    Sous réserve de compilation.

  5. #5
    Membre éprouvé Avatar de alexrtz
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2003
    Messages
    639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2003
    Messages : 639
    Par défaut
    Salut,

    Citation Envoyé par MK.Djahli Voir le message
    Je me suis dit qu'il fallait décomposer la chaine de caractères en caractères que je pourrais mettre dans un tableau de caractères (ça fait beaucoup de caractères :S !), mais je voie pas comment ?!
    Le type "tableau de caractères" est hérité du C et on va en général essayer de l'éviter en C++.
    Ici tu veux mettre les éléments dans le tableau de caractères afin de la parcourir, mais tu peux parcourir la chaîne directement de la même manière
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (int i = 0; i < cc.size(); ++i) {
        cout << cc[i] << " ";
    }
    Je suppose que le but de l'exercice est de vous faire implémenter "à la main" les algorithmes.

    Juste garde en tête que le C++ vient avec une bibliothèque standard qui fournit des conteneurs (http://en.cppreference.com/w/cpp/container) et des algorithmes (http://en.cppreference.com/w/cpp/algorithm) très utiles et que tu devras connaître plus tard si tu veux continuer le C++.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char tc[1000] = cc; // Mais là, ça ne marche pas :( ! Pourtant, c'est une variable de type "string" !
    cc est une variable de type std::string, qui définit les chaînes de caractères dans la bibliothèque standard du C++.
    tc est un tableau de caractères (hérité du langage C).
    Ces deux types ne sont pas les mêmes et on ne peut pas assigner une string à un char[].

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    i++ /*  ou "++i" ? Quelle différence ? :p  */
    i++ est l'opérateur de post-incrémentation et ++i l'opérateur de pré-incrémentation.

    Le choix entre i++ et ++i a deux impacts:
    - sur l'assignation de i à une autre variable
    - sur les performances quand i est un type complexe (par exemple une matrice d'entiers)

    Concernant l'assignation,
    équivaut à
    et
    équivaut à
    Au niveau des performances, je ne vais pas rentrer dans les détails mais l'opérateur de post-incrémentation implique de faire une copie de la variable en interne.
    Pour certains types plus évolués que les entiers (ou les autres types primitifs du C++), la copie peut prendre du temps et cela impactera les performances de ton programme.

    Sauf si tu as vraiment besoin de faire une post-incrémenation (par exemple pour assigner la valeur d'une variable avant de l'incrémenter), il est conseillé d'utiliser la pré-incrémentation par défaut.

    Quelques remarques de plus générales

    Il est préférable d'initialiser une variable quand on la déclare
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int nbVoyelles = nombreVoyelles(chaine);
    et non de le faire en deux étapes déclaration puis initialisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int nbVoyelles;
    nbVoyelles = nombreVoyelles(chaine);
    La raison est que, tant qu'elle n'est pas initialisée, une variable contient "n'importe quoi", ce qu'il vaut mieux éviter

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cout<<"\n Saisissez votre chaine de caract\212re :\n "; cin>>chaine;
    Essaye de mettre une instruction par ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cout<<"\n Saisissez votre chaine de caract\212re :\n ";
    cin>>chaine;
    C'est plus lisible

  6. #6
    Membre chevronné Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 57
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 376
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    int compterVoyelles(const std::string& s)
    {
      return std::count_if(s.begin(), s.end(), [](char c) {
        switch(c) {
          case 'a':
          case 'A':
          [...]
          case 'Y':
            return true;
          default:
            return false;
        }
      });
    }
    a vue de nez
    Pourquoi ne pas continuer à utiliser la STL et la fonction find plutôt que ce gros switch/case. Avantage : les voyelles sont contenues dans une chaine de caractères plus facile à compléter avec les voyelles oubliées (ùéèàâä...) que le switch.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int compterVoyelles(const std::string& s)
    {
        std::string voyelles ("aeiouAEIOIàäâéèëêïîöôuù"); //liste partielle, il en manque encore plein.
     
        return std::count_if(s.begin(), s.end(), [&](char c) {
            return (voyelles.find(c) == std::string::npos) ? false : true;
        });
    }

  7. #7
    Membre averti
    Homme Profil pro
    Etudiant en Mthématique et informatique
    Inscrit en
    Octobre 2014
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Algérie

    Informations professionnelles :
    Activité : Etudiant en Mthématique et informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Octobre 2014
    Messages : 15
    Par défaut
    Bonjour,
    Désolé pour la réponse tardive ! Il y a une coupure d'Internet dans tout le pays , mais je suppose que vous le savez déjà ^^...peu importe.
    Alors, tout d'abord merci à vous tous pour vos réponses même si certains d'entre vous avaient oublié que je suis un Débutant en programmation, pourtant je l'avais bien mentionné tout en haut...J'aimerais plutôt éviter d'utiliser les fonctions et les procédures dans les bibliothèques standard et construire moi même l'algorithme mais si c'est très compliqué pour moi en tant que débutant et qu'il vaudrait mieux les utiliser alors je suis toujours preneur.

    Citation Envoyé par alexrtz Voir le message
    Je suppose que le but de l'exercice est de vous faire implémenter "à la main" les algorithmes.
    alexrtz, ta réponse m'a beaucoup aidé alors je te remercie beaucoup et effectivement c'était ça le but .

    Citation Envoyé par alexrtz Voir le message
    Ici tu veux mettre les éléments dans le tableau de caractères afin de la parcourir, mais tu peux parcourir la chaîne directement de la même manière
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (int i = 0; i < cc.size(); ++i) {
        cout << cc[i] << " ";
    }
    Cependant, j'ai parcouru la chaine de caractère comme tu me l'avais dit mais apparemment quand je la parcoure elle s’arrête juste avant le premier espace , si je comprends bien cette méthode permet de parcourir une chaine sans les espaces et autres caractères, quelque chose comme ça "SalutToutLeMonde!", ce qui ne répond pas vraiment à mes intentions !
    J'ai cherché un peu sur Internet pour résoudre ce problème mais sans issu...j'ai même essayé de remplacer les espaces par un autre caractère mais ça marche pas. Y-a-il un moyen pour régler cela ?

    Voici le code après avoir suivi tes instructions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    #include<iostream>
    using namespace std;
     
    int nombreVoyelles(string cc)
    {
    	int nv=0;
    	for(int i=0; i<cc.length(); i++)
    	{
    		if(((cc[i]=='a') || (cc[i]=='e') || (cc[i]=='i') || (cc[i]=='o') || (cc[i]=='u') || (cc[i]=='y'))  ||  ((cc[i]=='A') || (cc[i]=='E') || (cc[i]=='I') || (cc[i]=='O') || (cc[i]=='U') || (cc[i]=='Y')))
    		{
    			nv++;
    		}
    	}
     
    	return nv;
    }
     
    int main()
    {
    	cout<<"\n         - Nombre de voyelles contenues dans une chaine de caract\212res -\n\n";
     
    	string chaine;
    	cout<<"\n Saisissez votre chaine de caract\212re sans les espaces :\n "; 
    	cin>>chaine;
     
    	int nbVoyelles = nombreVoyelles(chaine);
     
    	cout<<"\n\n Votre chaine de caract\212res contient "<<nbVoyelles<<" voyelles !";
     
    	return 0;
    	system("pause");
    }

  8. #8
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 032
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 032
    Billets dans le blog
    12
    Par défaut
    Le fait que ça s'arrête au premier espace ne provient pas du parcours de la chaîne, mais de la manière dont tu la demandes à l'utilisateur.
    En effet, std::cin >> chaine; va récupérer ce que l'utilisateur a saisi, en s'arrêtant au premier espace rencontré.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 144
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par fenkys Voir le message
    Pourquoi ne pas continuer à utiliser la STL et la fonction find plutôt que ce gros switch/case. Avantage : les voyelles sont contenues dans une chaine de caractères plus facile à compléter avec les voyelles oubliées (ùéèàâä...) que le switch.
    Pourquoi complexifier le code en lui imposant des data dans une chaine en RAM et lui demander de faire un algo lineaire la ou on peut utiliser le compilateur pour (tres certainement) tranformer ca de O(n) a O(1) ?
    Quant a la lisiblite, ca n'engage que toi, je prefere un switch.
    Et dans ton cas, tu as des caracteres multibytes (ces conneries a accent que je n'ai pas sur mon clavier ) qui ne tiennent pas dans un std::string, il faudrait un wstring.
    Donc ton seul "avantage" c'est de pouvoir choisir quelles sont les voyelles dans la langue choisie au runtime. Ce qui sort de loin du scope de la question initiale amha.

    Cependant, j'ai parcouru la chaine de caractère comme tu me l'avais dit mais apparemment quand je la parcoure elle s’arrête juste avant le premier espace , si je comprends bien cette méthode permet de parcourir une chaine sans les espaces et autres caractères, quelque chose comme ça "SalutToutLeMonde!", ce qui ne répond pas vraiment à mes intentions !
    J'ai cherché un peu sur Internet pour résoudre ce problème mais sans issu...j'ai même essayé de remplacer les espaces par un autre caractère mais ça marche pas. Y-a-il un moyen pour régler cela ?
    T'as pas du chercher loin : http://cpp.developpez.com/faq/cpp/?p...nt-des-espaces

    Alors, tout d'abord merci à vous tous pour vos réponses même si certains d'entre vous avaient oublié que je suis un Débutant en programmation, pourtant je l'avais bien mentionné tout en haut...J'aimerais plutôt éviter d'utiliser les fonctions et les procédures dans les bibliothèques standard et construire moi même l'algorithme mais si c'est très compliqué pour moi en tant que débutant et qu'il vaudrait mieux les utiliser alors je suis toujours preneur.
    Tu peux ecrire ca avec un bon vieux for et l'operateur [] de string, mais as-tu besoin de notre aide pour ca ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  10. #10
    Membre averti
    Homme Profil pro
    Etudiant en Mthématique et informatique
    Inscrit en
    Octobre 2014
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Algérie

    Informations professionnelles :
    Activité : Etudiant en Mthématique et informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Octobre 2014
    Messages : 15
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Merci infiniment ! Problème résolu.

    voici le résultat final :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    #include<iostream>
    #include <string> 
    using namespace std;
     
    int nombreVoyelles(string cc)
    {
    	int nv=0;
    	for(int i=0; i<cc.length(); i++)
    	{
    		if(((cc[i]=='a') || (cc[i]=='e') || (cc[i]=='i') || (cc[i]=='o') || (cc[i]=='u') || (cc[i]=='y'))  ||  ((cc[i]=='A') || (cc[i]=='E') || (cc[i]=='I') || (cc[i]=='O') || (cc[i]=='U') || (cc[i]=='Y')))
    		{
    			nv++;
    		}
    	}
     
    	return nv;
    }
     
    int main()
    {
    	cout<<"\n         - Nombre de voyelles contenues dans une chaine de caract\212res -\n\n";
     
    	string chaine;
    	cout<<"\n Saisissez votre chaine de caract\212re sans les espaces :\n "; 
    	getline(cin, chaine);
     
    	int nbVoyelles = nombreVoyelles(chaine);
     
    	cout<<"\n\n Votre chaine de caract\212res contient "<<nbVoyelles<<" voyelles !";
     
    	return 0;
    	system("pause");
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [WD16] Executer formule contenu dans une chaine de caractère
    Par J0r_x dans le forum WinDev
    Réponses: 1
    Dernier message: 02/11/2011, 14h39
  2. Réponses: 8
    Dernier message: 16/05/2008, 10h34
  3. Réponses: 2
    Dernier message: 02/10/2007, 11h42
  4. [VB6] Parser XML contenu dans une chaine de caractère
    Par pegase06 dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 10/09/2007, 11h35
  5. Réponses: 2
    Dernier message: 12/01/2004, 13h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo