1

I am implementing this:

double x;
ostringstream x_convert;
x_convert << x;
string x_str = x_convert.str();

It seems a bit superfluous. Is there a more elegant way?

krsteeve
  • 1,794
  • 4
  • 19
  • 29
Plamen
  • 650
  • 1
  • 8
  • 27
  • 1
    duplicate? http://stackoverflow.com/questions/7228438/convert-double-float-to-string – JAL Oct 30 '13 at 18:09
  • 3
    Don't tag this question `[C]`. `ostringstream`, `.str();`, are `[C++]` only, not `[C]` – abelenky Oct 30 '13 at 18:21
  • You could just wrap the whole thing in a function so you do less typing. C++11 did this for you, `std::to_string()`, as everyone pointed out. The problem is lack of control on how the string looks like. – DanielKO Oct 30 '13 at 18:33

5 Answers5

10

Are you using C++11? If so, there's:

auto x_str = std::to_string(x);
Barry
  • 286,269
  • 29
  • 621
  • 977
4

std::to_string:

std::string x_str = std::to_string(x);
David G
  • 94,763
  • 41
  • 167
  • 253
3

What you have is the safest method (pre-C++11).

Alternatively, you could so something like:

double value = SOME_VALUE;
char buffer[100] = {};
sprintf(buffer, "%f", value);
std::string s = buffer;

Which is functionally equivalent to what std::to_string does. You must be careful to have enough space allocated for buffer, and (as you can see), you are still writing about 4 lines of code to do this conversion, so it is no more (nor less) elegant than the other methods.

If you are stuck in pre-C++11, you can implement your own to_string by doing something like:

template<typename T>
std::string to_string(T t)
{
    std::ostringstream oss;
    oss << t;
    return oss.str();
}

Which will work for any type that already has an overload for std::ostream& operator<<(std::ostream&, T&).

Zac Howland
  • 15,777
  • 1
  • 26
  • 42
  • Um, there's nothing in this use of `sprintf` that is not "safe"; it will work just fine. – Pete Becker Oct 30 '13 at 18:51
  • @PeteBecker As I've allocated a buffer that is substantially larger than a floating point precision can be in this case, you are correct. If I change the size of `buffer` to 10, for example, it is no longer the case. – Zac Howland Oct 30 '13 at 18:53
  • Yes, if the code was different, the result could be different. But it's not, and the statement that it "is not safe as written" is wrong. – Pete Becker Oct 30 '13 at 18:56
  • Just take out the parenthetical. There's no need to take cheap shots at `sprintf`. – Pete Becker Oct 30 '13 at 19:00
2

Without C++11 you may write your own to_string function:

string to_string(double x) {
  ostringstream x_convert;
  x_convert << x;
  return x_convert.str();
}
vz0
  • 32,345
  • 7
  • 44
  • 77
1

With C++11, as mentioned by others, use std::to_string.

Without C++11, you are stuck with the code you've already written, or something along those lines. You can make the use of that code a bit more elegant (read: less typing) by constructing a device which does the string building for you:

class StringBuilder
{
public:
    template <typename T> inline StringBuilder& operator<<(const T& t)
    {
        mStream << t;
        return * this;
    }
    inline std::string get() const
    {
        return mStream.str();
    }
    inline operator std::string () const
    {
        return get();
    }
private:
    std::stringstream mStream;
};

Now you can:

double x;
string x_str = StringBuilder() << x;

But at the end of the day it's really just syntactic sugar for the same thing. There are similar devices in Boost -- I'd use those if you can.

John Dibling
  • 99,718
  • 31
  • 186
  • 324