convert string

Started by
6 comments, last by Zahlman 18 years, 3 months ago
const char * toString(std::stringstream *c, int num) { *c<< num; return (*c).str().c_str(); } Then I use this way stringstream c; char *a = toString(&c,33); but this not work.
Advertisement
The problem with your code is that
(*c).str().c_str();
is creating a temporary variable which is being destructed when the function exits, thus returning a garbage pointer for your string.

Try returning a string instead of a char* pointer.

std::string toString(int num){std::stringstream c; c << num;return c.str();}


Calling the function would be like toString(12345).c_str()
1) Use a reference to pass the stringstream rather than a pointer. Actually, don't pass one at all - there's no need for it, and it could mess things up (it makes things harder for the caller, and introduces the risk of there being something already in the stringstream's buffer and yielding an incorrect result. Passing a pointer also makes it harder than passing a reference, by introducing the risk of the pointer being null or invalid).

2) Returning a std::string is probably a better idea. If you return a char*, then it has to point to something valid, which means either to an existing buffer or to a new allocation, and either way you have memory management issues. If you really need a char* and you just can't stand to do the .c_str() on the caller side, you should probably pass a pointer to a buffer as a parameter (you could pass a char reference too, and get its address within the function, but that's a bit misleading in terms of documentation - the caller usually expects a reference to refer to a single object rather than an array - and the caller will usually already have a pointer value handy and not need to reference something):

void toString(int num, char* buffer) {  std::stringstream parser;  parser << num;  parser >> buffer;}char local[16]; // technically for a 32-bit integer you need 12:// up to 10 digits, a negative sign and a null terminatortoString(33, local);ceestyleApiCall(local);
I enjoy the template implementation:
template <class T>std::string toString(T obj){    std::stringstream s;     s << obj;    return s.str();}
Then it works with pretty much anything that the stringstream can handle.
Rob Loach [Website] [Projects] [Contact]
Use boost::lexical_cast
Don't forget that
std::string toString(std::stringstream &ss, int n){    ss << n;    return ss.str();}

Is entirely different from:
std::string toString(int n){    std::ostringstream ss;    ss << n;    return ss.str();}

Consider:
    int n = 1234;    std::stringstream ss;    ss << "n = ";    std::string n_as_str = toString(ss, n);    // what is the contents of n_as_str?


John B
The best thing about the internet is the way people with no experience or qualifications can pretend to be completely superior to other people who have no experience or qualifications.
Good point John B,
here's a new version with a ostringstream default parameter.

std::string toString(int n, std::ostringstream& ss = std::ostringstream()){    ss << n;    return ss.str();}
Quote:Original post by JohnBSmall
Don't forget that
*** Source Snippet Removed ***
Is entirely different from:
*** Source Snippet Removed ***
Consider:
*** Source Snippet Removed ***

John B


Yes, that's precisely what I was getting at. The functionality in the last example is unlikely to be desirable (and if it is, there is probably a problem with the function design). So passing a stringstream is needlessly complicated and breaks encapsulation of the process.

This topic is closed to new replies.

Advertisement