85

I have a float value that needs to be put into a std::string. How do I convert from float to string?

float val = 2.5;
std::string my_val = val; // error here
davidism
  • 121,510
  • 29
  • 395
  • 339
adam_0
  • 6,920
  • 6
  • 40
  • 52
  • 5
    Consider reading Herb Sutter's article "The String Formatters of Manor Farm" (http://www.gotw.ca/publications/mill19.htm). It provides examples of five of the most common ways to format things and discusses their advantages and disadvantages. – James McNellis Jan 24 '10 at 05:04

8 Answers8

161

As of C++11, the standard C++ library provides the function std::to_string(arg) with various supported types for arg.

omerfarukdogan
  • 839
  • 9
  • 26
dmckee --- ex-moderator kitten
  • 98,632
  • 24
  • 142
  • 234
  • 11
    Be aware of possible unexpected behaviour of std::to_string() when working with floats. (See output of examples on this link http://en.cppreference.com/w/cpp/string/basic_string/to_string). – Michael Konečný Apr 22 '16 at 13:35
  • 1
    this deserves to be promoted to the best answer because most build enviornment would have C++11 support already – deddebme Apr 26 '17 at 18:20
  • Following up on @MichaelKonečný's comment, quoting the same page, which got this update since then: _C++17 provides `std::to_chars` as a higher-performance locale-independent alternative._ – Sz. Jan 18 '23 at 00:25
64

Unless you're worried about performance, use string streams:

#include <sstream>
//..

std::ostringstream ss;
ss << myFloat;
std::string s(ss.str());

If you're okay with Boost, lexical_cast<> is a convenient alternative:

std::string s = boost::lexical_cast<std::string>(myFloat);

Efficient alternatives are e.g. FastFormat or simply the C-style functions.

Hossein
  • 24,202
  • 35
  • 119
  • 224
Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
  • This will be an adequate solution considering that these functions will be called rarely (resizing the window), but is there a more efficient method? – adam_0 Jan 24 '10 at 04:03
  • 1
    And if you're not okay with Boost, write your own lexical cast function; it's all of about five lines of code and makes for a most useful library function (see http://www.gotw.ca/publications/mill19.htm for the basic implementation). – James McNellis Jan 24 '10 at 05:01
  • 7
    For the first method, don't forget `#include `. – jackw11111 Aug 22 '18 at 22:09
  • 1
    @jackw11111, The header is a very important point that is all to often omitted from answers. It is especially problematic with c++ 'streams'. Thanks for pointing it out. I was going to do so if you had not. – Grant Rostig Dec 18 '19 at 00:13
31

Important: Read the note at the end.

Quick answer:

Use to_string() (available since C++11) example:

#include <iostream>
#include <string>

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

    return 0;
}

Run it yourself: http://ideone.com/7ejfaU

These are available as well:

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

Important Note:

As @Michael Konečný rightfully pointed out, using to_string() is risky at best that is its very likely to cause unexpected results. From http://en.cppreference.com/w/cpp/string/basic_string/to_string:

With floating point types std::to_string may yield unexpected results as the number of significant digits in the returned string can be zero, see the example. The return value may differ significantly from what std::cout prints by default, see the example. std::to_string relies on the current locale for formatting purposes, and therefore concurrent calls to std::to_string from multiple threads may result in partial serialization of calls. C++17 provides std::to_chars as a higher-performance locale-independent alternative.

The best way would be to use stringstream as others such as @dcp demonstrated in his answer:

This issue is demonstrated in the following example: run the example yourself: 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 information: 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;
}

Output:

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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Hossein
  • 24,202
  • 35
  • 119
  • 224
  • 3
    Be aware of possible unexpected behaviour of std::to_string() when working with floats. (See output of examples on this link http://en.cppreference.com/w/cpp/string/basic_string/to_string). – Michael Konečný Apr 22 '16 at 13:36
17

You can define a template which will work not only just with doubles, but with other types as well.

template <typename T> string tostr(const T& t) { 
   ostringstream os; 
   os<<t; 
   return os.str(); 
} 

Then you can use it for other types.

double x = 14.4;
int y = 21;

string sx = tostr(x);
string sy = tostr(y);
marcp
  • 1,179
  • 2
  • 15
  • 36
dcp
  • 54,410
  • 22
  • 144
  • 164
7

Use std::to_chars once your standard library provides it:

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
}

The advantages of this method are:

  • It is locale-independent, preventing bugs when writing data into formats such as JSON that require '.' as a decimal point
  • It provides shortest decimal representation with round trip guarantees
  • It is potentially more efficient than other standard methods because it doesn't use the locale and doesn't require allocation

Unfortunately std::to_string is of limited utility with floating point because it uses the fixed representation, rounding small values to zero and producing long strings for large values, e.g.

auto s1 = std::to_string(1e+40);
// s1 == 10000000000000000303786028427003666890752.000000

auto s2 = std::to_string(1e-40);
// s2 == 0.000000

C++20 might get a more convenient std::format API with the same benefits as std::to_chars if the P0645 standards proposal gets approved.

vitaut
  • 49,672
  • 25
  • 199
  • 336
4

You can use std::to_string in C++11

float val = 2.5;
std::string my_val = std::to_string(val);
Yochai Timmer
  • 48,127
  • 24
  • 147
  • 185
  • 3
    Heads up, don't copy-paste-submit-grace_period_edit answers. copy-paste-edit-submit them. We get an auto flag instead. Take care the next time. Cheers – Bhargav Rao Mar 27 '17 at 12:46
  • This is basically identical to @dmckee's answer from 2013. – vitaut Mar 24 '19 at 18:24
  • @Yochai when I `cout` the `my_val` gives 5.20000 but when you assigned `val` to 50.2 or more bigger then it gives not accurate output. Gives like: 50.000001 and 107.199997 (for 107.2). whats the reason of this? – Yunus Temurlenk Aug 16 '20 at 08:37
1

If you're worried about performance, check out the Boost::lexical_cast library.

David Gladfelter
  • 4,175
  • 2
  • 25
  • 25
  • 13
    I think you mean "if you're *not* worried about performance". `boost::lexical_cast` is about the heaviest solution you could pick! – Tom Jan 24 '10 at 06:03
-1

This tutorial gives a simple, yet elegant, solution, which I transcribe:

#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);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
tony gil
  • 9,424
  • 6
  • 76
  • 100