string and sprintf()

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().
Last edited on
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(), ...).
I think there is no way to do it.
(Only:
1
2
3
4
char ss[] = "a string";
std::string sd(strlen("This is !") + strlen(ss), '\0');

sprintf(const_cast<char*>(sd.c_str()), "This is %s!", ss);

But it's terrible!)
And why do you need to use exactly sprintf and string? std::ostringstream offers a better variant, I think..
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;

Hope this helps.
You're supposed to use snprintf.

e.g.
1
2
3
4
char ss[] = "a string";
std::string sd;

sprintf(sd, sizeof(sd), "This is %s!", ss);


EDIT: It's supposed to be:
1
2
3
char ss[] = "a string";

sprintf(ss, sizeof(ss), "This is %s!", "some string");
Last edited on
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!" 

I guess there's no better way.
Last edited on
My bad. I thought stringstream::str() was a pointer to the char buffer.
Thank you all for the answers. They confirmed the solution I suggested. When I wrote my second post there were no answers. Thanks again, cheers.
The snprintf() function is C99, and it has some issues.
http://linux.die.net/man/3/snprintf

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...
Topic archived. No new replies allowed.