J'ai une valeur float qui doit être mise dans un std::string
. Comment puis-je convertir de float en chaîne?
float val = 2.5;
std::string my_val = val; // error here
Sauf si vous êtes inquiet pour les performances, utilisez string streams :
std::ostringstream ss;
ss << myFloat;
std::string s(ss.str());
Si vous êtes d'accord avec Boost, lexical_cast <> est une alternative pratique:
std::string s = boost::lexical_cast<std::string>(myFloat);
Des alternatives efficaces sont par exemple. FastFormat ou simplement les fonctions de style C.
À partir de C++ 11, la bibliothèque C++ standard fournit la fonction std::to_string(arg)
avec différents types pris en charge pour arg
.
Vous pouvez définir un modèle qui fonctionnera non seulement avec les doublons, mais aussi avec les autres types.
template <typename T> string tostr(const T& t) {
ostringstream os;
os<<t;
return os.str();
}
Ensuite, vous pouvez l'utiliser pour d'autres types.
double x = 14.4;
int y = 21;
string sx = tostr(x);
string sy = tostr(y);
Important:
Lire la note à la fin.
Réponse rapide :
Utilisez to_string()
. (disponible depuis c ++ 11)
Exemple :
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string pi = "pi is " + to_string(3.1415926);
cout<< "pi = "<< pi << endl;
return 0;
}
lancez-le vous-même: http://ideone.com/7ejfaU
Ceux-ci sont également disponibles:
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);
Note importante:
Comme @Michael Konečný l’a justement souligné, l’utilisation de to_string()
présente au mieux des risques qui risquent d’entraîner des résultats inattendus.
De http://fr.cppreference.com/w/cpp/string/basic_string/to_string :
Avec les types à virgule flottante,
std::to_string
peut générer des résultats inattendus, car le nombre de chiffres significatifs dans la chaîne renvoyée peut être zéro, voir l'exemple.
La valeur de retour peut différer considérablement de ce questd::cout
imprime par défaut, voir l'exemple .std::to_string
s'appuie sur les paramètres régionaux en cours pour la mise en forme, et donc les appels simultanés àstd::to_string
à partir de plusieurs threads peuvent entraîner une sérialisation partielle des appels.C++17
fournitstd::to_chars
en tant que indépendant des paramètres régionaux. alternative.
Le meilleur moyen serait d’utiliser stringstream
comme d’autres, comme @dcp, dans sa réponse .:
Ce problème est illustré dans l'exemple suivant:
lancez l’exemple vous-même: https://www.jdoodle.com/embed/v0/T4k
#include <iostream>
#include <sstream>
#include <string>
template < typename Type > std::string to_str (const Type & t)
{
std::ostringstream os;
os << t;
return os.str ();
}
int main ()
{
// more info : https://en.cppreference.com/w/cpp/string/basic_string/to_string
double f = 23.43;
double f2 = 1e-9;
double f3 = 1e40;
double f4 = 1e-40;
double f5 = 123456789;
std::string f_str = std::to_string (f);
std::string f_str2 = std::to_string (f2); // Note: returns "0.000000"
std::string f_str3 = std::to_string (f3); // Note: Does not return "1e+40".
std::string f_str4 = std::to_string (f4); // Note: returns "0.000000"
std::string f_str5 = std::to_string (f5);
std::cout << "std::cout: " << f << '\n'
<< "to_string: " << f_str << '\n'
<< "ostringstream: " << to_str (f) << "\n\n"
<< "std::cout: " << f2 << '\n'
<< "to_string: " << f_str2 << '\n'
<< "ostringstream: " << to_str (f2) << "\n\n"
<< "std::cout: " << f3 << '\n'
<< "to_string: " << f_str3 << '\n'
<< "ostringstream: " << to_str (f3) << "\n\n"
<< "std::cout: " << f4 << '\n'
<< "to_string: " << f_str4 << '\n'
<< "ostringstream: " << to_str (f4) << "\n\n"
<< "std::cout: " << f5 << '\n'
<< "to_string: " << f_str5 << '\n'
<< "ostringstream: " << to_str (f5) << '\n';
return 0;
}
sortie:
std::cout: 23.43
to_string: 23.430000
ostringstream: 23.43
std::cout: 1e-09
to_string: 0.000000
ostringstream: 1e-09
std::cout: 1e+40
to_string: 10000000000000000303786028427003666890752.000000
ostringstream: 1e+40
std::cout: 1e-40
to_string: 0.000000
ostringstream: 1e-40
std::cout: 1.23457e+08
to_string: 123456789.000000
ostringstream: 1.23457e+08
Vous pouvez utiliser std :: to_string en C++ 11
float val = 2.5;
std::string my_val = std::to_string(val);
Si les performances vous inquiètent, consultez la bibliothèque Boost :: lexical_cast .
Utilisez std::to_chars
une fois que votre bibliothèque standard l’a fourni:
std::array<char, 32> buf;
auto result = std::to_chars(buf.data(), buf.data() + buf.size(), val);
if (result.ec == std::errc()) {
auto str = std::string(buf.data(), result.ptr - buf.data());
// use the string
} else {
// handle the error
}
Les avantages de cette méthode sont:
Malheureusement, std::to_string
a une utilité limitée avec une virgule flottante car il utilise la représentation fixe, arrondissant les valeurs faibles à zéro et produisant des chaînes longues pour les valeurs élevées, par exemple.
auto s1 = std::to_string(1e+40);
// s1 == 10000000000000000303786028427003666890752.000000
auto s2 = std::to_string(1e-40);
// s2 == 0.000000
C++ 20 peut obtenir une API std::format
plus pratique avec les mêmes avantages que std::to_chars
si la proposition P0645 standards est approuvée.
Ce tutoriel donne une solution simple, mais élégante, que je transcris:
#include <sstream>
#include <string>
#include <stdexcept>
class BadConversion : public std::runtime_error {
public:
BadConversion(std::string const& s)
: std::runtime_error(s)
{ }
};
inline std::string stringify(double x)
{
std::ostringstream o;
if (!(o << x))
throw BadConversion("stringify(double)");
return o.str();
}
...
std::string my_val = stringify(val);