Hello, I've a got a question.
How can I use std::string object as the first argument of sprintf(), i.e. write to std::string using the C function sprintf() instead of sstream, or some other kind of stream.
1 2 3 4 5
char ss[] = "a string";
std::string sd;
sprintf(sd, "This is %s!", ss); // of course this won't compile because
// sprintf expects char[], not a string
I thought of using string::c_str(), but it returns const char[] and const_cast-ing it is not a bright idea.
Is there another way I can get std::string to behave like a writable char[]?
Again, I need to use a string and I need to use sprintf().
sprintf() is susceptible to buffer overruns because there is no check as to whether the allocated buffer is large enough to hold the data. What you need to do (in your example) is make sd a std::stringstream. When you create it, you give it a size (make it large enough, again, to avoid buffer overruns) and then you call sprintf(sd.str(), ...).
std::stringstream::str() returns a std::string, so that still won't work. If you are going to use a stringstream anyway, just use the usual stream options:
1 2 3 4 5
char cs[] = "a string";
std::ostringstream ss;
ss << "This is " << cs << "!";
std::cout << ss.str() << std::endl;
Again, I need to use a string and I need to use sprintf().
All known implementations of std::string::c_str() simply return a pointer to the strings internal buffer, so if you don't mind the possibility that it may break someday, you could just cast it, as you thought:
1 2 3 4 5 6 7 8 9
char cs[] = "a string";
std::string s;
s.reserve( 100 ); // You had better have room for what you are sprintf()ing!
s.resize( std::max( 0,
sprintf( (char*)s.c_str(), "This is %s!", cs )
) );
std::cout << s << std::endl;
However, best use is simply to use an intermediate buffer:
1 2 3 4 5 6 7 8 9 10
char cs[] = "a string";
std::string s;
{
char sb[ 100 ]; // You had better have room for what you are sprintf()ing!
sprintf( sb, "This is %s!", cs );
s = sb;
}
std::cout << s << std::endl;
I figured it out. I just create a temporary char[], I do the writing into it and then assign the contents of the char[] string into the std::string.
The code goes like this:
1 2 3 4 5
char ss[] = "a string";
std::string sd;
char stemp[100] = "";
snprintf(stemp, 100, "This is %s!", ss); // I use the safer version of sprintf() -- snprintf()
sd = stemp; // the contents of sd are now "This is a string!"
It is a good function though. Personally, I just play very carefully and stick to sprintf(), as it is always possible to determine a good upper limit for things you are sprintf()ing, even with locale issues. But that is just me...