23.4 — Stream classes for strings

So far, all of the I/O examples you have seen have been writing to cout or reading from cin. However, there is another set of classes called the stream classes for strings that allow you to use the familiar insertions (<<) and extraction (>>) operators to work with strings. Like istream and ostream, the string streams provide a buffer to hold data. However, unlike cin and cout, these streams are not connected to an I/O channel (such as a keyboard, monitor, etc…). One of the primary uses of string streams is to buffer output for display at a later time, or to process input line-by-line.

There are six stream classes for strings: istringstream (derived from istream), ostringstream (derived from ostream), and stringstream (derived from iostream) are used for reading and writing normal characters width strings. wistringstream, wostringstream, and wstringstream are used for reading and writing wide character strings. To use the stringstreams, you need to #include the sstream header.

There are two ways to get data into a stringstream:

1) Use the insertion (<<) operator:

2) Use the str(string) function to set the value of the buffer:

There are similarly two ways to get data out of a stringstream:

1) Use the str() function to retrieve the results of the buffer:

This prints:

12345 67.89

2) Use the extraction (>>) operator:

This program prints:

12345 - 67.89

Note that the >> operator iterates through the string -- each successive use of >> returns the next extractable value in the stream. On the other hand, str() returns the whole value of the stream, even if the >> has already been used on the stream.

Conversion between strings and numbers

Because the insertion and extraction operators know how to work with all of the basic data types, we can use them in order to convert strings to numbers or vice versa.

First, let’s take a look at converting numbers into a string:

This snippet prints:

12345 67.89

Now let’s convert a numerical string to a number:

This program prints:

12345 67.89

Clearing a stringstream for reuse

There are several ways to empty a stringstream’s buffer.

1) Set it to the empty string using str() with a blank C-style string:

2) Set it to the empty string using str() with a blank std::string object:

Both of these programs produce the following result:


When clearing out a stringstream, it is also generally a good idea to call the clear() function:

clear() resets any error flags that may have been set and returns the stream back to the ok state. We will talk more about the stream state and error flags in the next lesson.

23.5 -- Stream states and input validation
23.3 -- Output with ostream and ios

35 comments to 23.4 — Stream classes for strings

  • Math

    I hope this isn't an absurd question but why is stringstream and all the other streams important? Why can't we just stick to the normal way of defining strings?

  • Alek

    Hey,we extract the string until it reaches a whitespace is there a way to extract the whole string ?(no via .str())because it extracts as many characters as it sees in the buffer.what I mean is even if we have added two different string to the buffer we can extract all of the contents of the first one.


    • nascardriver

      Can you provide an example of input and expected output? `std::getline` might be what you're searching for.

      • Alek

        ty for your reply,I tried the following code but it extracts both of the c-style string inserted into the buffer not the first one alone.ain't there any way to extract them separately ?

        the output is like this: Hello WroldYou are so unfair :(
        however what I want is:  Hello World

        • nascardriver

          `std::stringstream` doesn't remember when you used `<<`, it only remembers the value, which is "Hello WorldYou are so unfair :(". You need to insert a line feed after the first string so that the extraction operations know when a line is over

          • Alek

            I'm curious about something,when we use os >> myStr. it doesn't remove anything from buffer right ? if it did we couldn't get the whole string put into buffer via os.str() later. then how does os know to extract the next string from buffer when we use `<<` operator for the next times ? I'm not referring to the above code I'm speaking generally. I hope I could make My point.

            Thx as always!

  • Chris

    Hi Alex and nascardriver,

    one question I couldn't really figure out from this chapter is (if there is, my mistake, please direct me to it):

    Is it possible to extract the "-/+" as a char in the following example? (There are spaces between each character in the string expression)

    Thank you for any help in advance.</sstream></string></iostream>

    • Chris

      Update. I know I can do this in the else part:

      But is there any better way of doing so?

      • nascardriver

        I don't think so. You either have to extract a character and put it back into the stream if it's not the one you expected or your have to predict the content (eg. assuming there's always an operator after an opening brace).

  • Lucky Abby


    I need help for my test code regarding stringstream, here is the code

    The problem is the getline function is not able to read int and double value.
    Is there workaround for getline function work properly for this purpose?

    Your help and explanation are much appreciated.


    I found solution as follow:

    is there better solution?

    • nascardriver

      Don't use `getline` for numbers, use the normal extraction operator

      • Lucky Abby

        Hello nascardriver,

        Thank you for your suggestion.

        To use normal extraction operator, then the input string have to be modified to

        to become

        and changes at the extraction operator will be

        • nascardriver

          Sorry I didn't see that you had comma separated values. It's possible to tell `iss` to treat ',' as the separator character, but that's a rather tedious process. If you want to ignore a single character, you can call `iss.ignore()`

          This works without modifications to your input string.

  • Tushar

    what if I want hello world to be treated as a single one?
    Edit: After researching I found, there is std::noskip(Manipulator) but that doesn't seem to be working.
    though the following method works:

    **OUTPUT** Hello World

  • Sheeplie

    For something like this, how does os know to stop at the space between the two numbers and give nValue1 the first portion, 12345 and nValue2 the second portion, 67.89?

  • Lokesh

    I think "There are six string classes for streams:" should be "There are six stream classes for string:"

  • Devashish

    Formatting Error:

    "There are similarly two ways to get data out of a stringstream: 1) Use the str() function to retrieve the results of the buffer:"

    Point 1) should be placed in a new line.

    I have some confusions regarding to this code. The output is 12345, that is the value of variable strValue, a hyphen and 67.89, that is value of variable strValue2.

    Allow me to read the code after the point where we are inserting a string of numbers into the stream. Stream holds 12345 67.89. Then we define a variable, extract the value from the stream and try to put it in the variable strValue. According to output, srtrValue is only assigned 12345 (in string form) and 67.89 was not extracted from the stream to be set as the value of strValue. Why? Does the whitespace breaks the extraction process (and all these things are related to the fact that >> can't read whitespaces)? Is my question clear?

    When I do this

    I got an address. Seeing that, I am sure that cout << os; is not invalid and has some meaning. What's that?
    From this point, I can see an important use of this functionality that I can ask user for a (integral or double) number, keep that in a string variable and then using the above functionalities, insert the input into stringstream and then finally extract the contents in the buffer to make it a valid value for an integer or double variable. That way, if a user tries to input something non-integral, the program won't end up in an infinite loop and I would be able to handle this situation manually.

    2) Call erase() on the result of str():

    where are we calling erase???

    • Alex

      Thanks for pointing out the formatting error. Fixed.
      1) Yes, whitespace breaks the formatting. If you remember from the lessons on cin, if you extract cin to a string, you only get up to the first whitespace. If you want the whole string, you have to use another method, like cin.getline().

      2) When I tried to compile this snippet in Visual Studio:

      I got an error about an invalid conversion. I'm not sure why your compiler is printing an address. Perhaps it's doing an implicit conversion to a pointer value.

      3) Update the erase example to remove the incorrect reference to erase().

  • NagaRaju

    Please use os.clear() before the line os << "12345 234234" << endl;

  • Knight

    In the code given below, it is printing value of s2 but not printing value of S1. Can someone help me why it is the case?

    using namespace std;

    int main()
    stringstream os;

    int nD=234234;
    os << nD;
    string s2;
    os >> s2;
    cout << s2 << endl;

    os << "12345 234234" << endl;

    string S1;
    os >> S1;
    cout << S1 << endl;
    os >> S1;
    cout << S1 << endl;

    return 0;

  • mustsafa

    Hello, or should I say "Hello world!". I am still learning C++, and I would appreciate anyone how would help me.

    I am trying to make a C++ program that would arrange three words in alphabetical order. Note that I did one for arranging three integers from least to greatest. Any help?

  • Auasp

    I Don't see any erase() function called.

  • serenity

    Templates (covered later in this tutorial) can help you create a pretty nice, generic Convert function, that converts between arbitrary compatible values, such as strings and different number types (and even custom classes, if they overload operator<< and operator>> properly).


  • Hi Alex,

    There is an error in the section Clearing a stringstream for reuse. The second suggestion of using erase does not work. I think this is because os.str() returns a copy of the buffer and erase then just erases the copy leaving the original in tact. So the code in this case will still print "Hello World!"

    Another point to note is that setting a buffer using str("xx") and then using the << operator on the stream will not append (as I at first thought) but will overwrite. So the following code:

    stringstream os;
    os << "World!";
    cout << os.str() << endl;

    will output:


  • Hi Alex,
    First a typo in the >> example, the comment says "print the numbers separated by a dash" but the code just prints the first value.

    Second you need to include < sstream > to get at stringstream.

    Third, the behaviour of >> and str() is subtly different as shown by this code:

    stringstream os;
    os << "12345 67.89"; // insert a string of numbers into the stream
    string strValue;
    os >> strValue; // extract 1st value
    cout << "value1 " << strValue << endl;
    os >> strValue; // extract 2nd value
    cout << "value2 " << strValue << endl;
    cout << "whole string " << os.str() << endl; // print whole string!

    which gives the following output:

    value1 12345
    value2 67.89
    whole string 12345 67.89

    In other words the >> operator takes values from the string, moving along every time it is used, but the str() function always returns the whole string no matter how many times it is called (even after using >>)

Leave a Comment

Put all code inside code tags: [code]your code here[/code]