web-dev-qa-db-fra.com

Convertit float en std :: string en C++

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
58
adam_0

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.

51
Georg Fritzsche

À 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.

105
dmckee

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);
16
dcp

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 que std::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 fournit std::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 
12
Breeze

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

float val = 2.5;
std::string my_val = std::to_string(val);
5
Yochai Timmer

Si les performances vous inquiètent, consultez la bibliothèque Boost :: lexical_cast .

2
David Gladfelter

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:

  • Il est indépendant de l'environnement local, empêchant ainsi les bogues lors de l'écriture de données dans des formats tels que JSON qui nécessitent '.' comme un point décimal
  • Il fournit la représentation décimale la plus courte avec des garanties aller-retour
  • Il est potentiellement plus efficace que d’autres méthodes standard car il n’utilise pas les paramètres régionaux et ne nécessite aucune allocation.

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.

2
vitaut

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);
0
tony gil