Doing sprintf stuff with std::string?

Started by
7 comments, last by Zahlman 18 years, 9 months ago
Hi, I'm just teaching my self STL at the moment and I'm stuck on a small problem, which I haven't been able to find a satisfactory answer to yet. Basically I have some code that does something like this... int my_number = 5; char my_text[128]; sprintf(my_text, "My number is %d", my_number); I want to convert this over to use std::string instead of a char array but I'm not sure how to do the sprintf part. So it should look something like this... int my_number = 5; std::string my_text; // put "My number is 'my_number'" into my_text??? I'm sure it is very easy, but since STL is very new to me (as of today), I'm sort of floundering around.
Advertisement
You will use techniques as posted on this thread to accomplish this.
std::stringstream sstr;sstr << "My number is "sstr << 49;// When you need to use the entire stringstd::string str1 = sstr.str();
A little about the philosophy here - In C, sprintf is "to string, print formatted". It shares common internal workings with the normal printf() and the fprintf() family of functions. The idea is that you're supposed to be able to treat a string as if it were a file - an early experiment in polymorphism, though a very crude one. (And yes, there is sscanf() too, etc.)

In C++, that idea is preserved - but now our "strings" are real objects as opposed to just null-terminated char data in the same format as the program's string literals, and "files" are real objects as opposed to pointers to whatever FILE really is on your system. Our file objects implement a concept (something the language can't really check, but basically referring to the set of functions provided) of a "stream", which strings don't - because while it should be possible to treat a string as if it were a file, it's not the normal way of interacting with one.

To bridge the gap, the library provides "stringstream", an object that behaves like a stream, but has an in-memory string of data as its "target" - and allows us to convert the buffer to a string, or set the buffer to a string's contents. (We don't get to assume that there's an actual std::string embedded in the stringstream; it could be doing something else for efficiency reasons, but the .str() method is guaranteed to give us back a std::string object that represents the buffer's contents.) And since we're dealing with objects, and part of C++ design philosophy is "don't alias things unless the user was explicitly asking for it by using pointers", you get a separate copy, such that the two objects can be mutated independently of each other. (This is in contrast to what happens in C when you try to assign char*'s around all over the place, and forget to use strcpy() where appropriate.)

(Aside: I both like and dislike this philosophy. It's quite at odds with the Java (and also Python and C#) way of doing things, where everything is aliased unless you ask for a copy. That way saves making redundant copies of things, and is quite convenient in other ways too - frequently you *want* those changes to objects to be "shared", and when you don't, often you'd rather not change the object at all, in hindsight. But actually, I think both ways are "appropriate" for their respective languages - the aliasing way works a lot better when you already have "objects are references", garbage collection, and methods being virtual implicitly rather than explicitly.)
You can also try boost::format which will give a syntax closer to sprintf().
Well.. .c_str() works for me. try it.
Quote:Original post by ACCU
Well.. .c_str() works for me. try it.


Given that std::string keeps track of the length of the string internally, if you take the pointer returned by std::string::c_str(), cast the constness away (it returns a const char*) and use it as sprintf()'s target, Bad Things™ will happen.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
When I try to use std::stringstream I get this...

error C2079: 'sstr' uses undefined class 'std::basic_stringstream<_Elem,_Traits,_Alloc>'
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Alloc=std::allocator<char>
]

I've had a search around google, but couldn't find anything constructive. I'm assuming that I'm not including something, but I don't know what exactly.
#include <sstream>
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
And <string> as well, of course. :)

This topic is closed to new replies.

Advertisement