Stringstreams are one of three C++ style input/output buffers available through the c++ standard library: file streams, string streams and array streams, though array streams are deprecated. Just like file streams read to and from a file, string streams will read to and from a string.
Their operators are just like file streams, too: operator>>
will read information into a variable using the source data from the stream to determine the result, and operator<<
will place the data from the right-hand operand into the stringstream. Any function which operates on an istream
will operate on an istringstream
and similarly any function which operates on an ostream
will operate on an ostringstream
, since the stringstreams inherit from those respective base classes.
The internal buffer for the stringstreams can be accessed by calling their member function str()
which gets or sets the underlying string object
I've mostly seen input stringstreams used as a method of placing text data into variables when the original string was available only all at once, and when applying tokenization to specific parts of larger text data. Another use case could be passing in a string to a function which needs different information depending on the information in the string: [Coliru]:
void doDifferentThingsFromString(const std::string &str){
std::string
command;
std::istringstream
stream{str}; // construct an input string stream
stream >> command;
if(command == "line"){
std::cout << stream.str() << '\n';
}
else{
std::cout << "not line!\n";
}
}
int main(){
doDifferentThingsFromString("line Alice and \nBob were having an adventure.");
doDifferentThingsFromString("well this won't print anything at all");
}
outputs
line Alice and
Bob were having an adventure.
not line!
Though of course the second call did in fact print something--just not the supplied argument.
On the other hand, output stringstreams are useful for conversion of sequences of data into strings. Say you have an integer and a double and you want to display them reversed. Unfortunately, for some reason your compiler doesn't have the set of standard library functions for to_string
implemented. Maybe you have another class, Foo
, which is a bit more complicated to print, and you already have a printing function for it, and you don't want to write a string conversion function for just this little bit of code. Good news! you don't have to!
With an ostringstream
, you can simply read data into your stream like you would with a file stream, then get the resulting string, and manipulate the string however you wish. [Coliru]:
std::string reverse(const std::string &original){
return std::string{original.rbegin(), original.rend()};
}
void printReversed(int integer, double floatingPoint){
std::ostringstream
stream;
stream << integer << ", " << floatingPoint;
std::cout << reverse(stream.str()) << '\n';
}
template <typename Container_>
void printContainer(std::ostream &out, const Container_ &container){
for(auto &&element : container){
out << element << ", ";
}
out << "\n";
}
int main(){
printReversed(17, 43.21);
std::ostringstream
stream;
printContainer(stream, "never eat soggy waffles");
std::cout << reverse(stream.str()) << "\n";
}
outputs
12.34 ,71
, ,s ,e ,l ,f ,f ,a ,w , ,y ,g ,g ,o ,s , ,t ,a ,e , ,r ,e ,v ,e ,n
There is also a stringstream
which operates like the fstream
and allows both input and output operations. All three stringstream types have narrow and wide variants. More information is available on the wiki:
istringstream
ostringstream
stringstream