8.5. String StreamsThe iostream library supports in-memory input/output, in which a stream is attached to a string within the program's memory. That string can be written to and read from using the iostream input and output operators. The library defines three kinds of string streams:
To use any of these classes, we must include the sstream header. Like the fstream types, these types are derived from the iostream types, meaning that all the operations on iostreams also apply to the types in sstream. In addition to the operations that the sstream types inherit, these types have a constructor that takes a string. The constructor copies the string argument into the stringstream object. The operations that read and write the stringstream read or write the string in the object. These classes also define a member named str to fetch or set the string value that the stringstream manipulates. Note that although fstream and sstream share a common base class, they have no other interrelationship. In particular, we cannot use open and close on a stringstream, nor can we use str on an fstream.
Using a stringstreamWe've seen programs that need to deal with their input a word at a time or a line at a time. The first sort of programs use the string input operator and the second use the getline function. However, some programs need to do both: They have some processing to do on a per-line basis and other work that needs to be done on each word within each line. Using stringstreamslets us do so: string line, word; // will hold a line and word from input, respectively while (getline(cin, line)) { // read a line from the input into line // do per-line processing istringstream stream(line); // bind to stream to the line we read while (stream >> word){ // read a word from line // do per-word processing } } Here we use getline to get an entire line from the input. To get the words in each line, we bind an istringstream to the line that we read. We can then use the normal string input operator to read the words from each line. stringstreams Provide Conversions and/or FormattingOne common use of stringstreams is when we want to obtain automatic formatting across multiple data types. For example, we might have a collection of numeric values but want their string representation or vice versa. The sstream input and output operations automatically convert an arithmetic type into its corresponding string representation or back again: int val1 = 512, val2 = 1024; ostringstream format_message; // ok: converts values to a string representation format_message << "val1: " << val1 << "\n" << "val2: " << val2 << "\n"; Here we create an empty ostringstream object named format_message and insert the indicated text into that object. What's important is that the int values are automatically converted to their printable string equivalents. The contents of format_message are the characters val1: 512\nval2: 1024 We could retrieve the numeric value by using an istringstream to read from the string. Reading an istringstream automatically converts from the character representation of a numeric value to its corresponding arithmetic value: // str member obtains the string associated with a stringstream istringstream input_istring(format_message.str()); string dump; // place to dump the labels from the formatted message // extracts the stored ascii values, converting back to arithmetic types input_istring >> dump >> val1 >> dump >> val2; cout << val1 << " " << val2 << endl; // prints 512 1024 Here we use the str member to obtain a copy of the string associated with the ostringstream we previously created. We bind input_istring to that string. When we read input_istring, the values are converted back to their original numeric representations.
Because the input operator reads typed values, it is essential that the types of the objects into which we read be compatible with the types of the values read from the stringstream. In this case, input_istring had four components: The string value val1: followed by 512 followed by the string val2: followed by 1024. As usual, whenweread strings using the input operator, whitespace is ignored. Thus, when we read the string associated with format_message, we can ignore the newlines that are part of that value.
|