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 :

Itérateur sur string et str.erase


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2012
    Messages : 3
    Par défaut Itérateur sur string et str.erase
    Salut à tous,
    je débute sur C++,
    à chaque fois que j'ai un problème je cherche sur le net l'erreur que m'affiche mon compilateur pour comprendre d'où vient mon erreur, mais là je sèche

    je cherche à manipuler des string par le biais d'un itérateur

    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
     
    {
    	string str1("abcd");
    	string str2("xyz");
    	string::iterator it(str1.begin());
     
    	cout << *it << endl;   // affiche 'a'
    	str1.erase(it);   // supprime 'a'
    	cout << str1 << endl;  // affiche "bcd"
    	str1.insert(it, str2.begin(), str2.end());  // insert "xyz" au début de "bcd"
    	cout << str1 << endl;  // affiche donc "xyzbcd"
    	cout << *it << endl;  // affiche 'b' donc l'itérateur pointe sur 'b'
    	str1.erase(it);  // devrait donc supprimer 'b' 
    	cout << str1 << endl;  // mais ici il affiche "yzbcd", il a donc supprimé 'x' !?!?
    }
    d'autant plus que j'ai droit à une erreur d'accès à la mémoire à la fin de l’exécution du programme... jusqu'à un core dumped...
    je compile avec g++, mais il n'affiche aucune erreur à la compilation

    quelqu'un aurait-il une réponse à ce comportement particulier de l'itérateur ?
    Merci.

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    Il me semble que la bonne syntaxe est :

    Sinon un itérateur n'est pas un pointeur même s'il se comporte tout comme.

    Il est possible que derrière l'itérateur (simple hypothèse) il y ai un pointeur sur la valeur "pointée" par l'itérateur pour l'utilisation des opérateurs * et ->.
    Et à côté, il peut y avoir une autre autre variable pour faciliter les opérations ++, -- ainsi que les opérations de suppressions et d'insertions d'où tes résultats incohérents.

    J'ai essayé de regarder le code source des itérateurs mais.... j'ai pas compris grand chose
    Si ça t'intéresse ou si ça peut aider quelqu'un pour nous expliquer ce qui se cache derrière un iterateur : http://www.sgi.com/tech/stl/stl_iterator_base.h

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2012
    Messages : 3
    Par défaut
    Bonjour Neckara,
    merci pour ta réponse

    effectivement, après avoir jeté un oeil à cplusplus.com,
    erase revoie un itérateur si on rentre un itérateur
    string& erase ( size_t pos = 0, size_t n = npos );
    iterator erase ( iterator position );
    iterator erase ( iterator first, iterator last );
    mais où se situe alors ce nouvel itérateur ? je vais faire des tests pour voir... cette méthode me paraît des plus obscures


    après quelques manip,
    je pense qu'en modifiant le string, on modifie aussi la chaine. Je veux dire qu'en supprimant un élément, on supprime le caractère et le pointeur vers le prochain élément. on "casse" donc la chaine qui se retrouve avec un NULL ou un '\0' au milieu (mais c'est une supposition...) et qui donc pertube le bon déroulement de l'itérateur le long de la chaine.

    exemple:
    strint str("abcd"); //chaine initiale :

    'a' -> 'b' -> 'c' -> 'd' -> '\0'
    begin()---------------------->end()

    str.erase(str.begin()+3);
    'a' -> 'b' -> '\0' 'd' -> '\0' //plus de lien entre le début et la fin
    begin()--------X |---------end()


    ce nouvel itérateur en sortie de erase est un itérateur à jour pour la nouvelle chaine, qui permettra de la parcourir de A à Z, sans se manger un end() au milieu.

    enfin, c'est juste une supposition... c'est la première fois que je me sers d'itérateurs

    ça m'aurait permis de simplifier le code si je le maîtrisais convenablement ^^ mais finalement pas tant que ça. Je vais m'en passer pour cette fois.
    Bon, en tout cas, ça mérite réflexion pour plus tard.

  4. #4
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    erase, que ce soit pour std::string, vector, list, ..., a toujours le même comportement : il supprime la donnée de l'itérateur passé en paramètre, puis retourne un itérateur sur l'élément suivant.
    La raison est très simple : comment veux-tu faire une opération sur ton itérateur après l'avoir supprimé et rendu invalide ? Tu ne peux pas, tu vas avoir un crash.
    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
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Bonjour,
    Citation Envoyé par bionesis Voir le message
    Je veux dire qu'en supprimant un élément, on supprime le caractère et le pointeur vers le prochain élément. on "casse" donc la chaine qui se retrouve avec un NULL ou un '\0' au milieu (mais c'est une supposition...)
    Non, on ne casse pas la chaine.
    En fait la représentation sous-jacente d'une std::string est un tableau de char; lorsqu'on supprime un caractère au milieu, tous les caractères suivant sont recopiés d'un cran en arrière pour combler le trou.

    Donc on a :
    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
     
     
    begin()                                               end()
     |                                                       |
     v                                                       v   
    [0]   [1]    [2]    [3]     [4]    [5]    [6]    [7]
    'a' -> 'b' -> 'c' -> 'd' -> 'e' -> 'f' -> 'g' -> 'h' ->
     
    str.erase(str.begin()+3);
     
     
    begin()                                        end()
     |                                                |
     v                                                v   
    [0]   [1]    [2]    [3]     [4]    [5]    [6]   
    'a' -> 'b' -> 'c' -> 'e' -> 'f' -> 'g' -> 'h' ->
    Du coup il faut faire un peu attention avec erase() sur les std::string très longues. Si par exemple on supprime le premier caractère (str.erase(str.begin()) d'une chaine d'un million de caractères alors les 999999 caractères suivants vont tous être recopiés en cran en arrière !

  6. #6
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2012
    Messages : 3
    Par défaut
    ok, merci pour vos réponses à tous les deux,
    ça clarifie beaucoup de choses, je comprends mieux

    Bionesis.

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

Discussions similaires

  1. Question sur String variable = new String( )
    Par beegees dans le forum Langage
    Réponses: 12
    Dernier message: 14/05/2007, 21h38
  2. cherche site sur les fonctions str
    Par LesLemmings dans le forum Visual C++
    Réponses: 2
    Dernier message: 18/04/2007, 16h48
  3. tests sur String
    Par frouge dans le forum Collection et Stream
    Réponses: 1
    Dernier message: 07/06/2006, 11h38
  4. Caster un objet sur string !!
    Par maximus001ma dans le forum Langage
    Réponses: 3
    Dernier message: 06/06/2006, 13h02

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