[Résolu][Débutant C++]strchr

Statut
N'est pas ouverte pour d'autres réponses.
P

PeGaZe

ex membre
Voilà j'aimerais savoir faire que qd je tape un mot (par exemple : rififi) il me donne le nombre de i contenu dans le mot et que ce nombre soit attaché à une variable nbrei par exemple. J'ai eu des infos sur strchr mais elle ne fonctionnent pas.... Savez-vous m'aider?

Merci
 

Jereck

Α & Ω
Staff
Si tu peux perdre le texte de départ sans problèmes :
Code:
int nbri = 0, Buffer;
char Texte[X] = "Rififi";
char Lettre = 'i';


do {
    Buffer = strchr (Texte, Lettre);
    if (Buffer != NULL){
         nbri++;
        Texte = Texte + Buffer + 1;
    }

}while (buffer != NULL);
Sinon :
Code:
int nbri = 0, Buffer;
char Texte[X] = "Rififi", char TxtBuff[X];
char Lettre = 'i';

strcpy (TxtBuff, Texte);
// Copie de sauvegarde de Texte

do {
    Buffer = strchr (Texte, Lettre);
    // Buffer continet l'emplacement du premier 'i' trouvé

    if (Buffer != NULL){    // Si pas de 'i' trouvé, Buffer == NULL
         nbri++;               // Un 'i' trouvé en plus
         TxtBuff = TxtBuff + Buffer + 1;
    // On déplace le pointeur de la tête de la chaine, à la 
    // position du 'i' trouvé + 1 (pour ne pas le "re-découvrir" à 
    // chaque itération de la boucle)

    }

}while (Buffer != NULL);

D'un coup, je suis prit d'un doute. préviens-moi si ça ne marche pas (chuis trop fatigué pour tenter de réfléchir à fond sans être sur que ce seera utile)
 
T

theodorus

ex membre
Voici un exemple (en C), au cas où ceux de Jereck ne marcheraient pas (ce que je craint, mais bon moi je n'ais jamais eu de cours de programmation :) ):

Code:
#include <stdio.h>

int 
main (void)
{
  char Texte[] = "blablabla";
  char * Lettre  = "a";
  int Nombre   =  0 ;

  Nombre = strchr2 (Texte, *Lettre);

  printf("J'ai trouvé %i fois \"%c\" dans \"%s\"\n", Nombre, *Lettre, Texte);

  return 0;
}


int 
strchr2 (char * Chaine,
	 int Carac)
{
  int Compteur = 0;

  while (Chaine = strchr (++Chaine, Carac)) Compteur++;
  
  return Compteur;
}
(L'utilisation d'une fonction est là pour limiter l'utilisation de la mémoire.)
 

kaRma

Drink Fast Corp.
peeeeeeeeeeeeeeegaaaaaaaaaaaaz
 
1er
OP
P

PeGaZe

ex membre
Oui merci pour les infos, je les tests demain aprèmidi car le je suis chez moi :p Jvous tiens au courant

Merci déjà pour les aides !
 
T

theodorus

ex membre
Oui mais c'est pour démontrer, ne recopie pas bêtement mon implémentation dans ton programme final, tu risques d'avoir des surpises...
 

SesK

Touriste
PeGaZe a dit:
Oui merci pour les infos, je les tests demain aprèmidi car le je suis chez moi :p Jvous tiens au courant

Merci déjà pour les aides !
tu travaille que a l'ecole ? :roll:

si je boss que a l ecole j'aurais jamais fini mes applic moi
 
PeGaZe a dit:
Voilà j'aimerais savoir faire que qd je tape un mot (par exemple : rififi) il me donne le nombre de i contenu dans le mot et que ce nombre soit attaché à une variable nbrei par exemple. J'ai eu des infos sur strchr mais elle ne fonctionnent pas.... Savez-vous m'aider?

Merci
Code:
/* aide pour un gamerz
*/
#include <iostream>
#include <string>
using namespace std;

int main(int argc, char* argv[])
{
    string s="rififi";  // ta chaîne de caractère :D
    char c = 'i';       // le caractère a rechercher, intéressant pour une fct
    int nb_de_i=0;      // le nombre qu'une telle fct pourrait retourner

    for (unsigned i=0 ; i<s.size() ; i++)   // parcours
        if (s[i] == c)                      // condition
            nb_de_i++;                      // ++
    cout << "le nombre de \"" << c << "\" est de : " << nb_de_i;
    getchar();                              // une fonction pour attendre une
    return 0;                                   // entrée clavier...
}
 
Code:
/* aide pour un gamerz 
*/ 
#include <iostream>     // pour tes cin/cout notamment
#include <string>       // pour utiliser la classe string propre au C++ (STL)
using namespace std;    // pour pas devoir utiliser l'opérateur de résolution
                            // de portée...

// prototype de la fonction
const int cpt_char(const string s, const char c);

int main(int argc, char* argv[])
{
    cout << "le nombre de \"i\" est dans rififi : " << cpt_char("rififi", 'i');
    getchar();                              // une fonction pour attendre une
    return 0;                                   // entrée clavier...
}

/* définition de ta fonction :
    en entrée : une chaîne de type string et le caractère à "compter"
    */
const int cpt_char(const string s, const char c) {
    int nb_de_i=0;                          // compteur
    for (unsigned i=0 ; i<s.size() ; i++)   // parcours
        if (s[i] == c)                      // condition
            nb_de_i++;                      // ++
    return nb_de_i;                         // retour du résultat du compteur
}
la version en utilisant une fonction (assimilable à son type de retour)
 
T

theodorus

ex membre
D'accord mais il me semble que tu parcours la chaîne deux fois (je ne vois pas trop l'utilité.)
On pourrait l'optimiser dans ce cas-ci mais si "rififi" n'était pas constant?
 
theodorus a dit:
D'accord mais il me semble que tu parcours la chaîne deux fois (je ne vois pas trop l'utilité.)
On pourrait l'optimiser dans ce cas-ci mais si "rififi" n'était pas constant?
?? parcours 2 x ??
où?

const string ne veut pas dire que rififi doit être constant mais qu'on ne doit pas le modifier dans la fonction...
 
T

theodorus

ex membre
Une première fois dans s.size() (car c'est bien un string C, n'est-ce pas?)
La deuxièmme avec ta boucle for(){}
 
T

theodorus

ex membre
TITM4v3rick a dit:
const string ne veut pas dire que rififi doit être constant mais qu'on ne doit pas le modifier dans la fonction...
Non je voulais dire si par exemple il prenait la chaîne à traiter au hazard (donc taille imprévisible, donc pas d'optimisation possible du s.size() )
 
theodorus a dit:
Une première fois dans s.size() (car c'est bien un string C, n'est-ce pas?)
La deuxièmme avec ta boucle for(){}
c'est un string C++, c'est une classe Template prise dans librairie standard (STL : Standard Template Library), la lib du C++...

size() est une fonction qui renvoit la longueur de la chaîne de caractère... On peut aussi utiliser length.

la boucle for, elle, fait le parcours.
 
theodorus a dit:
TITM4v3rick a dit:
const string ne veut pas dire que rififi doit être constant mais qu'on ne doit pas le modifier dans la fonction...
Non je voulais dire si par exemple il prenait la chaîne à traiter au hazard (donc taille imprévisible, donc pas d'optimisation possible du s.size() )
LoL,

Code:
const int cpt_char(const string s, const char c) { 
    int nb_de_i=0;                          // compteur 
    for (unsigned i=0 ; i<s.size() ; i++)   // parcours 
        if (s[i] == c)                      // condition 
            nb_de_i++;                      // ++ 
    return nb_de_i;                         // retour du résultat du compteur 
}
le string "s" en entrée est un objet imprévisible...
Un utilisateur va tester avec :
Code:
cpt_char("rififi", 'i'); ===> 3
un autre avec :
Code:
cpt_char("salut les amis", 'X'); ===> 0
 
T

theodorus

ex membre
Par string C, je voulais dire terminé par un "\0". On ne peut mesurer la taille de ce genre de strings qu'en le parcourant du premier char au dernier. Les strings C++ sont donc différents?
 
T

theodorus

ex membre
TITM4v3rick a dit:
theodorus a dit:
TITM4v3rick a dit:
const string ne veut pas dire que rififi doit être constant mais qu'on ne doit pas le modifier dans la fonction...
Non je voulais dire si par exemple il prenait la chaîne à traiter au hazard (donc taille imprévisible, donc pas d'optimisation possible du s.size() )
LoL,

Code:
const int cpt_char(const string s, const char c) { 
    int nb_de_i=0;                          // compteur 
    for (unsigned i=0 ; i<s.size() ; i++)   // parcours 
        if (s[i] == c)                      // condition 
            nb_de_i++;                      // ++ 
    return nb_de_i;                         // retour du résultat du compteur 
}
le string "s" en entrée est un objet imprévisible...
Un utilisateur va tester avec :
Code:
cpt_char("rififi", 'i'); ===> 3
un autre avec :
Code:
cpt_char("salut les amis", 'X'); ===> 0
Ton compilateur peut penser autrement. S'il voit que le string reste le même sur tout le programme il pourrait essayer de précalculer s.size()
 
theodorus a dit:
Par string C, je voulais dire terminé par un "\0". On ne peut mesurer la taille de ce genre de strings qu'en le parcourant du premier char au dernier. Les strings C++ sont donc différents?
hum, ici on parle d'orienté objet...
string (cfr STL) est une classe.

une classe est un moule à objets, une fabrique d'objets;
un objet est une instance d'une classe.

une classe est composée de membres données (privés) => masquage de l'information et de méthodes (publiques) => l'interface utilisateur...

string s;

s est une instance statique de la classe string.
string est implémentée d'une certaine manière (trop compliqué à expliquer en peu de lignes) et possède des méthodes, des fonctions membres qui permettent de se simplifier la vie (exemple : size, length, l'opérateur d'indiçage etc...)

=> Quand tu crées un string (C++) en utilisant #include <string> de la STL, tu crées une instance de la classe string, un objet, "un brol" qui encapsule des données (une chaîne de type C par exemple) et des méthodes qui portent sur ces données qui ne sont pas "accessibles" de l'extérieur sauf en passant par les fonctions membres.

Code:
class MaChaine {

private:
   /* une implémentation qui ne t'intéresse pas pour le
     moment
    */

public:
   // des méthodes diverses
   //... exemple :

   // pour connaître sa taille
   const int saTaille() const;

   // pour parcourir et même modifier un caractère à un certain endroit...
   char & operator[](int i);

};
Bon, la classe string => basic_string est implémentée de telle manière à ce que son utilisateur voit sa vie se simplifier...
Exemple, le mécanisme d'exception lancé lorsqu'on veut faire des conneries du type débordement ;)

Enfin, je peu pas faire un cours ici non + hein...
 
un compilateur ne va pas pré-calculer s.size() en "voyant" qu'une chaîne est la même tout le temps... Mais dis donc, tu me sorts quoi là ?!

:D :D :D
 
T

theodorus

ex membre
TITM4v3rick a dit:
string est implémentée d'une certaine manière (trop compliqué à expliquer en peu de lignes)
Merci mais je sais ce qu'est l'orienté objet. C'est justement de l'implémentation que je te parle depuis le début. Je ne sait pas comment les strings sont implémentés en C++, mais il y a de fortes chances que ce ne soient que des chaînes de charactères habillées, qui comme en C, se terminent par "/0" (c'est d'ailleurs la question que je t'avais posé). Pour cacluler sa longueur, la méthode size() va devoir parcourir toute la chaîne jusqu'à rencontrer "\0", avec moult itérations et incrémentations, et retourner la taille. Voilà où est la charge inutlile de ton programme, car tu pourrais compter les occurences du charctère à chercher sans te soucier de la taille, et stopper quand tu vois "\0". Tout ceci est bien sûr vrai si mon affirmation du début est correcte, ce que tu n'as ni infirmé ni confirmé avec ton "L'OOP pour les nuls".

Bon, la classe string => basic_string est implémentée de telle manière à ce que son utilisateur voit sa vie se simplifier...
Tellement qu'il en oublie les bases et crée des algos atrocement lents sans s'en rendre compte.
 
Statut
N'est pas ouverte pour d'autres réponses.
Haut