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

Visual C++ Discussion :

bug std::string sous VS2005 (MSVC8)


Sujet :

Visual C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut bug std::string sous VS2005 (MSVC8)
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	std::string s("abc");
    	std::cout << s.c_str() << " " << s.length() << std::endl;
    	s.assign(s.c_str(),s.length()+1);
    	std::cout << s.c_str() << " " << s.length() << std::endl;
    	s.assign("abc\0",4);
    	std::cout << s.c_str() << " " << s.length() << std::endl;
    Ben voilà, la deuxième ligne affiche "abc 3" au lieu de "abc 4".
    Sous MSVC6 c'est OK.

    Ce n'est pas le premier effet de bord que je trouve, il y en a aussi dans std::sort.

    Merci.

  2. #2
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par camboui Voir le message
    Ben voilà, la deuxième ligne affiche "abc 3" au lieu de "abc 4".
    C'est VC6 qui a un bug, je dirais, et ce ne serait pas le premier que j'aurais vu dans sa STL, d'ailleurs... VS8 a plutôt un bon support de la STL par rapport aux versions précédentes. Je pense que tu aurais le même résultat avec GCC, lui aussi devrait voir la deuxième chaîne comme étant de longueur 3.

    Le caractère zéro ne peut PAS faire partie d'une chaîne en C ou en C++, étant donné que c'est le caractère de fin de chaîne. Le résultat affiché est donc tout à fait cohérent, car une std::string rajoute d'elle-même ce fameux zéro terminal.
    Tu aurais eu le même résultat en C en utilisant strlen avec des char[], d'ailleurs.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  3. #3
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Tu n'as pas commenté la dernière ligne de mon petit exemple ("abc\0"). Il y a un zéro et il se trouve bien dans le std::string avec la bonne longueur 4.
    Les 2ème et 3ème assignation à std::string sont sensées obtenir un résultat identique. Le seule différence est que la 2ème assignation se fait à partir d'une (sous-)chaine contenue dans le std::string lui-même, ce qu'il détecte.

    Sinon je ne suis pas d'accord.
    Le caractère zéro qui se trouve à la fin d'une chaine de caractère (en C ou C++) fait partie de la chaine.
    La preuve est que sizeof() renvoit bien la taille d'une chaine statique avec le zéro (sizeof("")==1, sizeof("123")==4).
    strcpy, strlen, etc, sont des fonctions qui agissent jusqu'au premier caractère # 0. Elles ne sont pas utilisées par chat_traits<char> (et donc std::string) qui utilise memcmp, memcpy, memmove, etc. Seul strlen est utilisée quand la taille contenue dans un [char (const) *] ne peut être déterminée autrement.
    Aussi, rien n'empêche de mettre un zéro dans un std::string. Ceci est valide:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::string s("abc");
    s[0]='\0';
    s+='\0';
    std::cout << s.length() << std::endl;//affiche 4
    Et pour finir, je viens d'essayer sous MinGW (ou gcc 3.4.5) et j'ai bien 4 et non pas 3.

    EDIT: Et pour VC6 je suis d'accord. Je ne le metionnais pas à titre de référence mais plutôt de manière ironique: "si même lui affiche le bon résultat, il faut que les autres en fasse de même "

  4. #4
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par camboui Voir le message
    Sinon je ne suis pas d'accord.
    Le caractère zéro qui se trouve à la fin d'une chaine de caractère (en C ou C++) fait partie de la chaine.
    Non. La preuve :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char test_null[6] = "abc\0d\0" ;
    Essaie de trouver un strlen valant 6 avec cette chaîne...

    Le caractère zéro est terminal : tu peux si tu veux le considérer comme faisant partie de la chaîne ou non, ça n'a que peu d'importance réelle. Tout ce qui suit le caractère nul est purement et simplement ignoré.
    En fait, tu confonds "tableau de char" (pouvant contenir un nombre indéfini de caractères nuls, vu que l'on en connait à l'avance la longueur) avec une "chaîne de caractères", qui par nature même s'arrête au premier caractère nul rencontré.

    Or, sizeof opère sur la taille de l'élément : il renverra 6 pour mon exemple test_null, par exemple. Mais un strlen appliqué à cette même variable renverra 3... Parce que la première fonction considère la taille réelle de l'élément, alors que la seconde l'interprète comme une chaîne de caractère et s'arrête au premier zéro.

    Si tu ne veux pas être gêné par les caractères nuls, ce n'est pas std::string qu'il te faut utiliser, mais un std::vector<char>.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

Discussions similaires

  1. Réponses: 3
    Dernier message: 05/01/2007, 15h50
  2. [débutant] equivalent à sprintf pour les std::string
    Par Biosox dans le forum SL & STL
    Réponses: 22
    Dernier message: 26/08/2005, 12h46
  3. [DOM] Bug en DOM sous IE
    Par rekam dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 22/08/2005, 17h07
  4. cannot convert 'std::string' to 'System::String ^'
    Par broadhead dans le forum MFC
    Réponses: 1
    Dernier message: 14/06/2005, 11h37
  5. std::string, operator =
    Par tut dans le forum SL & STL
    Réponses: 10
    Dernier message: 05/11/2004, 12h07

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