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 :

Problème pour convertir un entier en String


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Points : 48
    Points
    48
    Par défaut Problème pour convertir un entier en String
    Bonjour,

    J'utilise std::ostringstream de la bibliothèque sstream pour faire passer mes entiers sous la forme de chaîne de caractères.

    Dans un programme tout simple, pas de souci, l'exemple suivant fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <iostream>
    #include <sstream>
     
    int main()
    {
    	std::ostringstream out;
    	int solution = 8;
     
    	out << solution;
    	std::cout << out.str() << std::endl;
    	return 0;
    }
    Mais quand j'intègre ça dans mon application multi-threadée, ça ne marche plus. J'utilise les Thread boost, j'appelle donc une méthode static de cette façon :

    Déclaration dans MaClasse.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    static void thread_MonThread(MaClasse * MaClasse);
    Appel dans MaClasse.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    boost::thread thread_MonThread(boost::bind(&MaClasse::thread_MonThread,this));
    dans ma MaClasse.
    Voici l'allure de mon Thread (pour l'instant très simple) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void MaClasse::thread_MonThread(MaClasse * pMaClasse)
    {
            std::ostringstream out;
    	int val = 8;
    	out << val;
    	std::string str = out.str();
    }
    et à la ligne j'ai un seg fault. Je ne comprend pas pourquoi, je dois mal gérer quelque chose. J'ai essayé de faire passer ma variable "out" en attribut de MaClasse et d'appeler une fonction privée qui retourne la String résultat. Mais même résultat : seg fault. Si qqun sait d'ou cette erreur peut venir, je suis preneur...

  2. #2
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Il n'y a pas de '\0' à la fin des stringstream. Tu dois l'ajouter avant l'appel de la méthode str().

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Points : 48
    Points
    48
    Par défaut
    Donc en gros la ligne bug parce qu'il essaie d'affecter à mon String une chaîne qui se termine que très longtemps après ce qu'elle devrait (quand par chance il croise le caractère \0 dans la mémoire) ?

    Alors pourquoi dans l'exemple simple il n'y a pas de problème ?

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Points : 48
    Points
    48
    Par défaut
    J'ai testé et c'est vrai que ça fonctionne en ajoutant le caractère, mais si tu peux m'expliquer, ça serait parfait.

    En tout cas merci à toi.

  5. #5
    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 174
    Points
    1 174
    Par défaut
    euh pour moi c'est sensé marcher sans "\0" à la fin, vu que ça renvoie une copie d'un std::string, .str().

    Non? ou je me trompe?

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Points : 48
    Points
    48
    Par défaut
    Oui c'est vrai que ça marche sans aussi. Le bug venait d'ailleur (une libération de mémoire appelée d'ailleur, et qui prenait effet pendant le traitement du thread de ma classe, forcément...)

  7. #7
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Faut pas confondre les (i/o)stringstream avec les std::string.

    Les premiers sont de la merdouillabaise, sans vouloir relancer la polémique sur les stream (que je n'utilise plus que pour faire du logging).

    Les seconds sont bien plus sympas.
    Et j'argumente avec ce petit 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
    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
    template<typename _I>
    struct make_unsigned
    {
    };
     
     
    template<>
    struct make_unsigned<int>
    {
    	typedef unsigned int type;
    };
     
     
    template<>
    struct make_unsigned<long>
    {
    	typedef unsigned long type;
    };
     
     
    template<>
    struct make_unsigned<long long>
    {
    	typedef unsigned long long type;
    };
     
     
    template<class _C, class _I>
    inline std::basic_string<_C, std::char_traits<_C>, std::allocator<_C> >
    	integral_to_basic_string(_I value)
    {
    	int const _MAX_DIGITS=( sizeof(_I)==4 ? 12 : (sizeof(_I)==8 ? 24 : -1) );
    	_C buf[_MAX_DIGITS];
    	_C *bufp=buf;
    	int neg=(value<0?1:0);
    	if (neg)
    		value=-value;
    	do
    	{
    		//do we really need to cast to unsigned ?
    		*bufp++=(_C)((make_unsigned<_I>::type)value % 10);
    		(*(make_unsigned<_I>::type *)&value)/=10;
    	}
    	while (value>0);
    	std::basic_string<_C, std::char_traits<_C>, std::allocator<_C> > s;
    	s.resize(bufp-buf+neg);
    	std::basic_string<_C, std::char_traits<_C>, std::allocator<_C> >::iterator
    		it_s=s.begin();
    	if (neg)
    		*it_s++='-';
    	while (bufp!=buf)
    	{
    		_C c=*--bufp;
    		*it_s++=(_C)(c+'0');
    	}
    	return s;
    }
    Exemples d'utilisation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    inline std::string i2stringa(int value)
    	{ return integral_to_basic_string<char,int>(value); }
    inline std::wstring i2stringw(long long value)
    	{ return integral_to_basic_string<wchar_t,long long>(value); }

  8. #8
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Vous me faites douter maintenant, je ne sais plus s'il y a un '\0' ou pas à la fin des stringstream lors de l'appel à .str().
    Où sont les experts des streams ?

  9. #9
    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 174
    Points
    1 174
    Par défaut
    j'ai jamais eu à rajouter quoique ce soit pour que ça marche... (et c'est utile)

    http://cpp.developpez.com/faq/cpp/?p...RINGS_numtostr

  10. #10
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    Citation Envoyé par camboui Voir le message
    Vous me faites douter maintenant, je ne sais plus s'il y a un '\0' ou pas à la fin des stringstream lors de l'appel à .str().
    Où sont les experts des streams ?
    Non il n'y a pas de '\0' a la fin d'un stringstream, pas plus qu'à la fin d'une std::string.

    Mais en C++ il n'y a pas besoin de '\0' à la fin des chaînes, c'est en C qu'il y en a besoin.

  11. #11
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Oubliez tout ce que j'ai dit, ce sont des anneries (moi et ma connaissance des streams...)

    Mais je ferais ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::cout << out.str().c_str() << std::endl;
    au lieu de ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::cout << out.str() << std::endl;

  12. #12
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Citation Envoyé par Sylvain Togni Voir le message
    Non il n'y a pas de '\0' a la fin d'un stringstream, pas plus qu'à la fin d'une std::string.

    Mais en C++ il n'y a pas besoin de '\0' à la fin des chaînes, c'est en C qu'il y en a besoin.
    Quand on appelle la méthode c_str() de string le '\0' est garanti à la fin.

  13. #13
    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 174
    Points
    1 174
    Par défaut
    ouais mais t'en a pas besoin pour std::cout non plus, il prend très bien les std::string

  14. #14
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    J'ai toujours un pied dans MSVC6 qui ne les prend pas bien...

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

Discussions similaires

  1. Réponses: 26
    Dernier message: 03/11/2008, 17h29
  2. [SQL2K] Problème pour convertir un timestamp en datetime !!
    Par MeHo_ dans le forum MS SQL Server
    Réponses: 8
    Dernier message: 04/03/2008, 12h02
  3. [FAQ] Convertir un entier en string
    Par marsupilami34 dans le forum C++
    Réponses: 2
    Dernier message: 20/07/2007, 17h06
  4. Réponses: 11
    Dernier message: 19/02/2007, 01h20
  5. [C#] Problème pour convertir .Color en .Brush
    Par pymouse dans le forum Windows Forms
    Réponses: 2
    Dernier message: 19/05/2005, 16h19

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