2008-12-01 10 views
134

J'ai besoin de stocker un double comme une chaîne. Je sais que je peux utiliser printf si je voulais l'afficher, mais je veux juste le stocker dans une variable chaîne afin que je puisse le stocker dans une carte plus tard (valeur, pas la clé).Comment convertir un double en chaîne en C++?

+1

Pourquoi convertir tout? Stockez-le sur la carte en double et évitez les conversions vers et depuis. – EvilTeach

+0

Je stocke des chaînes dans la carte car j'ai plusieurs types à valider et à stocker. –

+2

Cela ressemble toujours à un appel d'objets. Un syndicat fonctionnerait. Chacun l'objet à insérer diverses valeurs dans lui, et l'avoir auto-valider. – EvilTeach

Répondre

157

Le boost (tm) façon:

std::string str = boost::lexical_cast<std::string>(dbl); 

Le standard C++ façon:

std::ostringstream strs; 
strs << dbl; 
std::string str = strs.str(); 

Remarque: Ne pas oublier #include <sstream>

+11

Merci. J'utilise la méthode Standard C++. –

+3

Je pense que boost :: lexical_cast est à peu près le moyen standard en C++, juste joliment emballé pour vous. BTW, litb, vous avez une faute de frappe mineur là - "boot: lexical_cast". –

+2

boost :: lexical_cast n'est pas simplement un simple wrapper autour du code stringstream. La plupart des routines de conversion sont implémentées en ligne. Selon les mesures de performance au bas de cette page (http://www.boost.org/doc/libs/1_47_0/libs/conversion/lexical_cast.htm), boost :: lexical_cast est plus rapide que l'utilisation de chaînes et, dans la plupart des cas, cas, plus rapide que scanf/printf – Ferruccio

0

Jetez un oeil à sprintf() et de la famille.

+0

Il a dit C++, pas C. :) – jalf

+2

Mais il a mentionné printf. – Darron

+2

J'ai mentionné printf parce que googling a trouvé un tas d'articles qui disent de convertir d'un double à une chaîne que vous utilisez printf. Ils font l'hypothèse que la seule chose que vous pourriez faire est d'imprimer, ce qui dans mon cas est faux. –

153
// The C way: 
char buffer[32]; 
snprintf(buffer, sizeof(buffer), "%g", myDoubleVar); 

// The C++03 way: 
std::ostringstream sstream; 
sstream << myDoubleVar; 
std::string varAsString = sstream.str(); 

// The C++11 way: 
std::string varAsString = std::to_string(myDoubleVar); 

// The boost way: 
std::string varAsString = boost::lexical_cast<std::string>(myDoubleVar); 
+1

Votre chemin C++ ne fonctionnera pas car 'operator <<' renvoie un 'std :: ostream &' plutôt qu'un 'stringstream &'. –

+0

Il me semble que mes strings sont un peu rouillées, je préfère les vieilles manières. Fixé maintenant (j'espère). –

+0

Votre code C m'a découragé au début. Je vous ai toujours mis en tête de donner des alternatives correctes. –

23

Si vous utilisez C++, évitez sprintf. C'est un-C++ y et a plusieurs problèmes. Stringstreams sont la méthode de choix, de préférence encapsulé dans Boost.LexicalCast qui peut être fait assez facilement:

template <typename T> 
std::string to_string(T const& value) { 
    stringstream sstr; 
    sstr << value; 
    return sstr.str(); 
} 

Utilisation:

string s = to_string(42.5); 
4

Heh, je viens d'écrire ceci (sans rapport avec cette question):

string temp = ""; 
stringstream outStream; 
double ratio = (currentImage->width*1.0f)/currentImage->height; 
outStream << " R: " << ratio; 
temp = outStream.str(); 

/* rest of the code */ 
9

sprintf est correct, mais en C++, la meilleure façon, plus sûre, et aussi légèrement plus lente de faire la conversion est avec stringstream:

#include <sstream> 
#include <string> 

// In some function: 
double d = 453.23; 
std::ostringstream os; 
os << d; 
std::string str = os.str(); 

Vous pouvez également utiliser Boost.LexicalCast:

#include <boost/lexical_cast.hpp> 
#include <string> 

// In some function: 
double d = 453.23; 
std::string str = boost::lexical_cast<string>(d); 

Dans les deux cas, str devrait être "453.23" après. LexicalCast a quelques avantages en ce qu'il garantit que la transformation est complète. Il utilise stringstream s en interne.

2

You may want to read my prior posting on SO. (Macro'ed version with a temporary ostringstream object.)

Pour mémoire: Dans mon propre code, je suis en faveur snprintf(). Avec un tableau char sur la pile locale, ce n'est pas si inefficace. (Eh bien, peut-être si vous avez dépassé la taille du tableau et bouclé pour le faire deux fois ...)

(Je l'ai également enveloppé via vsnprintf() .Mais cela me coûte une vérification de type. Yelp si vous voulez le code ...)

6

le problème avec lexical_cast est l'incapacité de définir la précision. Normalement, si vous convertissez un double en chaîne, c'est parce que vous voulez l'imprimer. Si la précision est trop ou trop petite, cela affectera votre sortie.

99

La façon standard C++ 11 (si vous ne vous souciez pas le format de sortie):

#include <string> 

auto str = std::to_string(42.5); 

to_string est une nouvelle fonction de bibliothèque introduite dans N1803 (r0), N1982 (r1) et (r2) "Simple Numeric Access". Il existe également la fonction stod pour effectuer l'opération inverse.

Si vous voulez un format de sortie différent de "%f", utilisez les méthodes snprintf ou ostringstream comme illustré dans les autres réponses.

+3

oh ouais bébé. to_string et stod les deux fonctionnent dans Visual Studio 11. – BSalita

+0

Oh chéri bébé ... to_string ne semble pas fonctionner dans VisualStudio 2010): Cela, ou je ne sais pas ce que je fais (très possible) – chessofnerd

+1

Cela devrait être plus haut, puisque c'est plus moderne! – gsamaras

0

Vous pouvez essayer un style plus compact:

std::string number_in_string; 

double number_in_double; 

std::ostringstream output; 

number_in_string = (dynamic_cast< std::ostringstream*>(&(output << number_in_double << 

std::endl)))->str(); 
9

Je regardais la C++ String Toolkit Libary. Juste posté une réponse similaire ailleurs. Je l'ai trouvé très rapide et fiable.

#include <strtk.hpp> 

double pi = M_PI; 
std::string pi_as_string = strtk::type_to_string<double>(pi); 
2

Normaly pour cette opérations, vous devez utiliser les ECVT, fcvt ou gcvt Fonctions:

/* gcvt example */ 
#include <stdio.h> 
#include <stdlib.h> 

main() 
{ 
    char buffer [20]; 
    gcvt (1365.249,6,buffer); 
    puts (buffer); 
    gcvt (1365.249,3,buffer); 
    puts (buffer); 
    return 0; 
} 

Output: 
1365.25 
1.37e+003 

En fonction:

void double_to_char(double f,char * buffer){ 
    gcvt(f,10,buffer); 
} 
0

Utilisez to_string().
exemple:

#include <iostream> 
#include <string> 

using namespace std; 
int main() 
{ 
    string pi = "pi is " + to_string(3.1415926); 
    cout<< "pi = "<< pi << endl; 

    return 0; 
} 

fonctionner vous-même: http://ideone.com/7ejfaU
Ces documents sont disponibles ainsi:

string to_string (int val); 
string to_string (long val); 
string to_string (long long val); 
string to_string (unsigned val); 
string to_string (unsigned long val); 
string to_string (unsigned long long val); 
string to_string (float val); 
string to_string (double val); 
string to_string (long double val); 
0

Vous pouvez convertir quelque chose à quoi que ce soit en utilisant cette fonction:

template<class T = std::string, class U> 
T to(U a) { 
    std::stringstream ss; 
    T ret; 
    ss << a; 
    ss >> ret; 
    return ret; 
}; 

utilisation :

std::string str = to(2.5); 
double d = to<double>("2.5"); 
6

Vous pouvez utiliser std::to_string en C++ 11

double d = 3.0; 
std::string str = std::to_string(d); 
Questions connexes