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 nombre caractère d'une chaîne


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 298
    Points : 67
    Points
    67
    Par défaut Compter nombre caractère d'une chaîne
    Bonjour tous le monde :

    J'ai crée une class String.

    J'aimerais faire une fonction qui me retournerais le nombre de caractère d'une chaîne.

    j'ai donc fait cette fonction :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
    int String::length()
    {
        int i = 0;
     
        while (_string[i] != '\0')
        {
    		cout << _string[i];
            i++;
        }
     
        return i;
    }
    Cependant j'ai une erreur, le programme ne retourne rien et bloque sur mon while.

    Voici mon main:

    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
     
     
     
    int main (int argc, char * const argv[]) {
        // insert code here...
     
    	String s1;
    	s1 = "hello "; 
    	String s2 = s1; 
    	s2 = "world"; 
    	String s3(", how are you"); 
    	//String s4 = '?'; 
    	//char*  s5 = s3; 
    	//cout << s5;
    	cout << s1 << s2 << s3 << endl ;
     
    	String s6; 
    	int l6 = s6.length();  // l6 == 0  //ça bloque donc sur cette ligne
    	/*String s7 = "hello"; 
    	int l7 = s7.length();  // l7 == 5 
    	//cout << l6;
    	//cout <<l7;*/
     
     
        return 0;
    }
    Voici le .h :

    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
     
     
    using namespace std; 
    #include <iostream>
     
    #ifndef _Sring
    #define _Strng
     
    class String {
     
    private:
     
    	char* _string; 
     
    public:
     
    	String();   //constructeur par défaut
    	~String();   // destructeur
    	String(const String &stringACopier);
    	String& operator=(const char  * aString);
    	String(const char * uneChaine);
    	operator char*() const;
    	char *getString();
    	friend ostream& operator<<(ostream&, String&);
     
    	int length();
    };
     
     
     
    #endif
    Voic mon .cpp :

    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
     
     
    #include "String.h"
    #include <iostream>
    using namespace std;
     
    String::String(){
     
    	_string = NULL;
     
    }
     
    String::~String(){
     
    	delete [] _string;
     
    }
     
    String::String(const String &stringACopier){
     
    	if( this != &stringACopier){
     
    		_string = new char[strlen(stringACopier._string)+1];	
     
    		if (_string != NULL){
    			strcpy (_string, stringACopier._string);
    		}
     
    	}
     
     
    }
     
     
     
    String& String::operator=(const char  * aString){
     
    		if (_string != NULL){
    			delete [] _string;
    		}
     
    		_string = new char[strlen(aString)+1];	
     
    		if (_string != NULL){
    			strcpy (_string, aString);
    		}
     
     
     
    	return (*this);
    }
     
    String::String(const char * uneChaine){
     
     
    	_string = new char[strlen(uneChaine)+1];	
     
    	if (_string != NULL){
    		strcpy (_string, uneChaine);
    	}
     
     
    }
     
     
    String::operator char*() const
    {
    	char* var;
     
    	strcpy (var,_string);
     
    	return var;
    }
     
     
     
    char* String::getString(){
     
    	return _string;
     
    }
     
     
    ostream& operator<< (ostream& flux, String &aString)
    {
    	flux << aString.getString();	
    	return flux;
    }
     
     
     
    int String::length()
    {
        int i = 0;
     
        while (_string[i] != '\0')
        {
    		cout << _string[i];
            i++;
        }
     
        return i;
    }

    Je vous remercie d'avance de vos réponse et vous souhaite de joyeuses fêtes.

  2. #2
    Membre averti Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Points : 323
    Points
    323
    Par défaut
    Bonjour,
    Ton constructeur pas défaut met _string a NULL, mais la méthode lenght ne test pas si _string est a NULL.
    Joyeuses fêtes!

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    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
    13
    14
    15
    16
    17
     
    String& String::operator=(const char  * aString){
     
    		if (_string != NULL){
    			delete [] _string;
    		}
     
    		_string = new char[strlen(aString)+1];	
     
    		if (_string != NULL){
    			strcpy (_string, aString);
    		}
     
     
     
    	return (*this);
    }
    _string ne peut jamais être nul dans le second cas.
    Note aussi que si ton allocation échoue, ta chaîne sera vidée au lieu de conserver l'ancienne valeur.

    Puisque tu calcules déjà la taille de ta chaîne un peu plus haut, tu peux aller plus vite en utilisant ensuite un memcpy.

    Sinon, pour ton length, tu peux tout simplement faire un strlen, ça ira d'ailleurs plus vite...
    Boost ftw

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 298
    Points : 67
    Points
    67
    Par défaut
    merci pour vos réponse, et pour strlen je ne peux pa l'utiliser c'est le but de l'exo.

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Pour commencer, je me permet une petite remarque en passant, bien qu'elle n'ait aucun rapport avec la question...

    Il faut réellement éviter l'utilisation des directives using (namespace) dans les fichiers d'en-tête.

    En effet, le fait de mettre ces directives dans un fichier d'ent-tête fait qu'elle va se répercuter sur l'ensemble des fichiers pour lesquels il y a une inclusion (même indirecte) du fichier dans lequel elle se trouve, avec le résultat final que tu *risque* toujours de vouloir créer une classe ou une structure qui entrera en conflit avec une classe ou une structure faisant partie de l'espace de noms pour lequel tu as défini la directive.

    Ensuite, j'avouerai que je suis un peu perplexe: tu nous dis ne pas pouvoir utiliser strlen, mais, si on regarde le code du constructeur prenant un const char* en paramètre... tu ne te gène absolument pas pour y recourir

    Si tu peux l'utiliser pour le constructeur, pourquoi ne pourrait-tu pas y recourir pour ta méthode length

    En outre, au niveau du constructeur en lui-même, il y a un risque qui n'est pas pris en compte et qui est de nature à poser problème: le fait que l'appel à ce constructeur pourrait très bien se faire sous la forme de Sting s(NULL);

    Enfin, pour ce qui concerne ton problème en lui-même...

    Je trouve, quelque part, dommage de "perdre" du temps à recompter tous les caractères d'une chaine à chaque fois que l'on souhaite avoir la taille, alors qu'il est tout à fait possible de le déduire une bonne fois pour toute en fonction de son contenu...

    Pourquoi ne pas, simplement, ajouter un membre à ta classe qui aurait pour objectif de... garder cette valeur en mémoire

    Tu initialiserait cette valeur dans les constructeurs sous les forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    String::String():l(0)
    {
        _string = new char(1);
        _string[0]='\0';
    }
    String::String(const char* aString):_length(aString? strlen(aString):0)
    {
        _string= new char(_length+1);
        if(aString && _string)
            strncpy(_string,aString, _length+1);
        }
    }
    et la méthode length deviendrait "simplement"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int String::length()
    {
        return _length;
    }
    Au passage, cette méthode est une candidate idéale pour devenir une méthode constante, ce qui devrait donner
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int String::length() const
    {
        return _length;
    }
    PS: cela s'écarte également de ton problème, mais tu devrais envisager l'idiome copy and swap pour ton opérateur =
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Je n'avais pas précisé que dans ce code

    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
    String& String::operator=(const char  * aString){
     
    		if (_string != NULL){
    			delete [] _string;
    		}
     
    		_string = new char[strlen(aString)+1];	
     
    		if (_string != NULL){
    			strcpy (_string, aString);
    		}
     
     
     
    	return (*this);
    }
    si l'allocation échoue après un delete[], string_ pointe vers de la mémoire invalide.
    Boost ftw

  7. #7
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    D'où l'intérêt de l'idiome copy and swap cité par koala..
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Idiom copy and swap qui a déjà fait l'objet d'un conseil dans un fil précédent pour le même exo...

Discussions similaires

  1. Réponses: 6
    Dernier message: 23/09/2017, 22h15
  2. Compter le nombre de / dans une chaîne de caractère
    Par Elodie11 dans le forum Shell et commandes GNU
    Réponses: 9
    Dernier message: 30/12/2011, 16h29
  3. Compter le nombre de caractére d'une chaîne
    Par koKoTis dans le forum VBScript
    Réponses: 8
    Dernier message: 03/04/2008, 12h35
  4. [WD12]Compter le nombre de caractère d'une chaîne
    Par Deallyra dans le forum WinDev
    Réponses: 10
    Dernier message: 07/03/2008, 16h05
  5. Compter le nombre de caractère d'une chaîne
    Par kespy13 dans le forum Langage
    Réponses: 3
    Dernier message: 19/04/2006, 18h04

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