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 :

Compter le nombre de chiffres dans un string


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Compter le nombre de chiffres dans un string
    Bonsoir,
    Je n'arrive pas à comprendre pourquoi mon programme ne veut pas compter le nombre d'occurrences des chiffres dans une string.
    La finalité de mon programme veut pouvoir afficher par exemple "a : 5" si la phrase comporte 5 a, majuscule et minuscule non différencié, pour ça ça marche. Mais impossible de compter les chiffres...
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     int c = 0, count[26] = {0}, cpt=0;
        string phrase;
        ofstream fichiertexte;
        fichiertexte.open("output.txt", ios::out); //on ouvre le fichier en ecriture
        if (fichiertexte.bad())
        {
            cout<<"Impossible d'ouvrir le fichier."<<endl;
        } //permet de tester si le fichier s'est ouvert sans probleme
     
        cout<<"Entrer une phrase a inserer dans le fichier."<<endl;
        cin.ignore();
        getline(cin,phrase);
        fichiertexte<<phrase;
    int taille=phrase.length();
    int calcul=0;
     
        for (int i = 0 ; i<phrase.length() ; i++)
        {
            phrase[i] = tolower(phrase[i]);
        }
     
        cout<<"Output :"<<endl;
    /*
        for(int k=0; k<10; k++) //de 0 à 9, donc ce que je veux rechercher
        {
            for (int z=0; z < taille; z++) //Je parcours tous les elements de ma phrase
            {
                if (phrase[z]==k) // Possible ?
                {
                   calcul++;
                }
               cout<< k << " : " <<calcul<<endl;
            }
     
        }
    */
    //OCCURR DES LETTRES
        while (phrase[c] != '\0')
        {
            if (phrase[c] >= 'a' && phrase[c] <= 'z' )
                count[phrase[c]-'a']++;
     
            c++;
        }
     
        for (c = 0; c < 26; c++)
        {
            if(count[c]!=0)
                cout<<(char)(c+'a')<<" : "<<hex<<count[c]<<endl;
            //On peut aussi faire :
            //printf("%c : %d\n",c+'a',count[c]);
        }
     
        fichiertexte.close();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /*
        for(int k=0; k<10; k++) //de 0 à 9, donc ce que je veux rechercher
        {
            for (int z=0; z < taille; z++) //Je parcours tous les elements de ma phrase
            {
                if (phrase[z]==k) // Possible ?
                {
                   calcul++;
                }
               cout<< k << " : " <<calcul<<endl;
            }
     
        }
    */
    Je ne comprends pas pourquoi cela ne marche pas. Pouvez vous m'éclairer svp?

    Merci et bonne soirée

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 073
    Points : 12 119
    Points
    12 119
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for(int k=0; k<10; k++) 
    {
        calcul = 0;
        for (int z=0; z < taille; z++)
        {
            if (phrase[z]== '0' + k)
            {
                calcul++;
            }
        }
        cout<< k << " : " <<calcul<<endl;
    }
    A l'arrache et que c'est sale.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Super ça marche un grand merci !
    Est-ce qu'il y aurait du coup une méthode plus propre ? J'ai essayé de faire pareil que pour les lettres mais j'obtiens des erreurs (lettres comptées en trop)
    Je débute en C++ du coup oui c'est un peu "sale" mais je vois pas d'autre moyen pour l'instant

  4. #4
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Il serait plus malin de parcourir la chaîne et faire un switch pour chaque valeur cherchée plutôt que de parcourir X fois la chaîne selon le nombre de valeurs à trouver.
    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.

  5. #5
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    C'est quoi propre, c'est quoi sale?

    Le sale pourrait correspondre à
    • du code difficile à lire
      • complexité inutile
      • nommages trompeurs ou trop courts
      • commentaires insuffisants, inutiles ou trompeurs
      • présentation et indentation farfelue
    • non robuste
      • supporte mal les évolutions
      • dépendant du contexte de compilation
    • 'miraculeux' (c-a-d fonctionne malgré des U.B.)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for ( char chif = '0' ;  chif <= '9' ; ++chif )  {
        unsigned calcul{};
        for ( auto car : phrase )
            calcul += (car == chif);
        std::cout << chif << " : " << calcul << std::endl;
    }
    Est-il plus propre ou plus sale?

    On peut dire que le code pour les lettres est sale
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        int c = 0;
        while ( phrase[c] != '\0' ) {
            if (phrase[c] >= 'a' && phrase[c] <= 'z' )
                count[phrase[c]-'a']++;
            c++;
        }
    * comment être sûr simplement que le tableau count[] ne déborde pas?
    * et tout cas, phrase[] déborde car dans une std::string le '\0' serait à l'indice phrase.length() qui est hors plage!

  6. #6
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 109
    Points
    6 109
    Par défaut
    Par difficulté croissante :
    • Code compréhensible par tout le monde :
      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
      #include <cctype>  // std::isdigit
      #include <cwctype> // std::iswdigit
      #include <string>
       
      size_t digitCount(const std::string& s)
      {
          size_t result = 0;
          for(size_t k = 0; k < s.length(); ++k)
              if(std::isdigit(s[k]))
                  ++result;
          return result;
      }
       
      size_t digitCount(const std::wstring& s)
      {
          size_t result = 0;
          for(size_t k = 0; k < s.length(); ++k)
              if(std::iswdigit(s[k]))
                  ++result;
          return result;
      }
      Il faut préférer std::isdigit(s[k]) qui est plus idiomatique que s[k] >= '0' && s[k] <= '9'.
    • Code un peu plus technique avec l'entête <algorithm> et des lamdbas :
      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 <algorithm> // std::count_if
      #include <cctype>    // std::isdigit
      #include <cwctype>   // std::iswdigit
      #include <string>
       
      size_t digitCount(const std::string& s)
      {
          return std::count_if(s.begin(), s.end(),
              [](char c) -> bool { return std::isdigit(c); });
      }
       
      size_t digitCount(const std::wstring& s)
      {
          return std::count_if(s.begin(), s.end(),
              [](wchar_t c) -> bool { return std::iswdigit(c); });
      }
      Quand on est familiarisé avec l'entête <algorithm> et les lambdas, cela se lit plus vite que les boucles for.
    • Code plus technique avec des templates et std::locale :
      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 <algorithm> // std::count_if
      #include <locale>    // std::isdigit (with locale)
      #include <string>
       
      template<class charT>
      size_t digitCount(const std::basic_string<charT>& s, const std::locale& loc = std::locale())
      {
          return std::count_if(s.begin(), s.end(),
              [&loc](charT c) -> bool { return std::isdigit(c, loc); });
      }
       
      template<class charT>
      size_t digitCount(const charT* s, const std::locale& loc = std::locale())
      {
          return digitCount(std::basic_string<charT>(s), loc);
      }
      C'est la solution la plus flexible, car on peut donner en paramètre une locale avec laquelle les chiffres ne sont pas forcément les caractères de '0' à '9'. Pour plus de détails, voir la doc de std::isdigit qui donne un exemple avec des caractères japonais.


    Remarque : Pour compter les lettres, c'est exactement pareil en remplaçant std::isdigit par std::isalpha.

  7. #7
    Membre du Club
    Homme Profil pro
    Etudiant-Benevole pour Electronic-MasterX
    Inscrit en
    Janvier 2015
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Islande

    Informations professionnelles :
    Activité : Etudiant-Benevole pour Electronic-MasterX
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2015
    Messages : 70
    Points : 44
    Points
    44
    Par défaut
    Salut.

    Pyramiddev je trouve votre solution un peu trop complexe pour un debutant surtout qu'il l'a précisé.

    la Solution premiére serait effectivement plus adequate pour lui pour un début et puis il pourra venir regarder la votre quand il saura ce que c'est que les Template

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 176
    Points
    1 176
    Par défaut
    Ca ressemblera plutôt à ça en C++:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #include <algorithm>
    #include <string>
    #include <cctype>
    #include <iostream>
     
    int main()
    {
        std::string s{"ab2c"};
     
        int tot = std::count_if( s.begin(), s.end(), isdigit );
     
        std::cout << tot << std::endl;
    }
    Il y a un piège avec la fonction isdigit, où pour ton cas la fonction C classique suffira je pense. Mais celle c++ (std::isdigit) demande une locale pour faire correspondre les chiffres écrits en différentes langues.

    Sinon tu peux écrire toi même tes fonctions "spéciales".
    Par ex:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    bool isA( char c )
    {
       return c == 'a' || c == 'A';
    }
     
    int main()
    {
    std::count_if( s.begin(), s.end(), isA);
    //...
     
    }
    Après tu peux en faire des functors (un objet qui fait office de fonction où tu pourrais passer la lettre cherchée en paramètre ), des lambdas (écrire directement le code dans l'algo) où que sais-je encore, mais tu ne connais ptet pas tout ça.

Discussions similaires

  1. [XL-2013] Compter nombre de chiffres dans un int.
    Par CristofMartins dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 18/04/2013, 09h46
  2. compter nombre d'occurence dans un String
    Par L4BiN dans le forum Collection et Stream
    Réponses: 13
    Dernier message: 24/11/2011, 01h25
  3. Compter nombre de chiffres dans une chaine
    Par D.Mounir dans le forum Excel
    Réponses: 2
    Dernier message: 18/06/2007, 12h28
  4. [SQL][ACCESS]Compter le nombres d'enregistrement dans deux..
    Par pc152 dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 05/06/2004, 12h30
  5. Réponses: 2
    Dernier message: 02/03/2004, 19h38

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