* How does stringstream work?
Someone kind of explained it like, in cout it sends it to "standard out stream" or something, and using stringstream, you stream it into that instead.

stringstream a; int b=12;  a << b;

* How can it convert characters into int and such?

char a = '2';
int b;
stringstream c;
c << a;
c >> b;

//now b = 2

* How does this work?

stringstream(someInt) >> out;

someInt is just a regular int.
Does it turn it into a stringstream.. or does it just somehow use it without turning it into a stringstream?
If it does turn it into a stringstream, does it mean someInt can no longer be used as an int?
like skipping over the stringstream varName(someInt)?

* Where does the garbage value come from?

string a1="13", a2="25";
    int b,c;
    stringstream d;

    d << a1;
    d >> b;

//it works if i put d.clear() here,
//but still wondering where that garbage value //came from

    d << a2;
    d >>c;

c produces some garbage value, but where is that garbage value coming from?
I can understand a pointer pointing somewhere random, getting a garbage value, but this?
25 -> d -> c. I don't get it?

Recommended Answers

All 6 Replies

Does it turn it into a stringstream.. or does it just somehow use it without turning it into a stringstream? If it does turn it into a stringstream, does it mean someInt can no longer be used as an int?

The integer is NOT turned into stringstream. Instead, stringstream will contain a copy of the integer converted to string. The value of someInt is not changed and could be used later on if you wish.

stringstream always contains its data in string format. If you initialize it with an integer then stringstream will convert it into a string of the integer's digits.

int someInt = 5;
stringstream s(someInt);

//or you can do this
stringstream s;
s << someInt;

Both the above have the same results, do it either way you wish. YOu can even add other text later on s << " Hello World"; If you print that, the result will be "5 Hello World". That leads to some intersting things that you can do with stringstream in order to format a string

stringstream s;
s << "Enter " << someInt << " number of names.";
cout << s.str() << '\n';

As for the garbage value of variable c, there was an error so c was not processed. Also note that you need to add seekg() statement to move d's file pointer back to the beginning of the string before converting to an integer.

#include <iostream>
#include <sstream>
#include <string>
using std::cout;
using std::stringstream;
using std::string;
using std::ios;
using std::begin;

int main()
{
    string a1="13", a2="25";
    int b = 0,c = 0;
    stringstream d;

    d << a1;
    d >> b;
    d.clear(); // clear EOF flag that was set in previous statement
    d << a2;
    d.seekg(0,ios::beg);
    d >> c;
    cout << "c = " << c << '\n';

}

]

What about these questions:

* How does stringstream work?
Someone kind of explained it like, in cout it sends it to "standard out stream" or something, and using stringstream, you stream it into that instead.

* If that is correct, shouldn't every cout or cin be followed by a .clear()?

* How can it convert characters into int and such?

]

As for the garbage value of variable c, there was an error so c was not processed. Also note that you need to add seekg() statement to move d's file pointer back to the beginning of the string before converting to an integer.

#include <iostream>
#include <sstream>
#include <string>
using std::cout;
using std::stringstream;
using std::string;
using std::ios;
using std::begin;

int main()
{
    string a1="13", a2="25";
    int b = 0,c = 0;
    stringstream d;

    d << a1;
    d >> b;
    d.clear(); // clear EOF flag that was set in previous statement
    d << a2;
    d.seekg(0,ios::beg);
    d >> c;
    cout << "c = " << c << '\n';

}

seekg? This seems so work fine for me:

* It's the >> that needs the clear()? Putting d.clear() after d << a2 doesn't work

int main()
{
    string a1="13", a2="25";
    int b = 0,c = 0;
    stringstream d;

    d << a1;
    d >> b;
    d.clear(); // clear EOF flag that was set in previous statement
    d << a2;
    d >> c;
    cout << "c = " << c << '\n';

}

* How does stringstream work?

That's a much deeper question than you probably think. But if you don't mind a heavily simplified code example, here's a simulation of stringstream:

#include <cstdio>
#include <cstdlib>
#include <ios>
#include <iostream>
#include <limits>
#include <string>

using namespace std;

namespace jsw {
    class faux_stringstream {
        ios::iostate _state;
        string _base;
    public:
        faux_stringstream();
        faux_stringstream(const string& init);
        
        bool good() const { return _state == ios::goodbit; }
        bool fail() const { return _state & ios::failbit; }
        bool eof() const { return _state & ios::eofbit; }
        
        operator bool() const { return good(); }
        
        faux_stringstream& operator<<(int value);
        faux_stringstream& operator<<(const string& value);
        
        faux_stringstream& operator>>(int& value);
        faux_stringstream& operator>>(string& value);
    };
    
    faux_stringstream::faux_stringstream() 
        : _state(ios::goodbit) {}
    
    faux_stringstream::faux_stringstream(const string& init)
        : _state(ios::goodbit), _base(init) {}
        
    faux_stringstream& faux_stringstream::operator<<(int value)
    {
        if (good()) {
            char buf[numeric_limits<int>::digits10 + 2];
            
            sprintf(buf, "%d", value);
            _base.append(buf);
        }
        
        return *this;
    }
    
    faux_stringstream& faux_stringstream::operator<<(const string& value)
    {
        if (good())
            _base.append(value);
        
        return *this;
    }
    
    faux_stringstream& faux_stringstream::operator>>(int& value)
    {
        if (_base.empty())
            _state = ios::eofbit;
        else if (good()) {
            char *end;
            
            value = (int)strtol(_base.c_str(), &end, 0);
            
            if (end != _base.c_str())
                _base.erase(0, end - _base.c_str());
            else
                _state = ios::failbit;
        }
            
        return *this;
    }
    
    faux_stringstream& faux_stringstream::operator>>(string& value)
    {
        if (_base.empty())
            _state = ios::eofbit;
        else if (good()) {
            string::size_type end = _base.find_first_of(" \t\n\r\f\v");
            string::size_type n = end == string::npos ? string::npos : end;
            
            value.assign(_base.substr(0, n));
            _base.erase(0, n);
        }
        
        return *this;
    }
}

int main()
{
    using jsw::faux_stringstream;
    
    faux_stringstream in;
    string src;
    int value;
    
    cout << "Enter a number: ";
    
    if (cin >> src && in << src && in >> value)
        cout << value << '\n';
}

* If that is correct, shouldn't every cout or cin be followed by a .clear()?

Not unless every cout or cin sets the eofbit. Note that in your code you read to the end of the stream, thus eofbit was set and needed to be cleared. This is consistent with how any other stream class works.

* How can it convert characters into int and such?

Are you asking how it does the conversion, or how to use the class for that purpose? Because your code suggests you already understand the latter well enough to write something functional.

* It's the >> that needs the clear()? Putting d.clear() after d << a2 doesn't work

Once any of the error flags are set on a stream, any reads or writes will fail immediately. Since it's the >> that set the eofbit, the next << will fail unless you call clear() first.

That's a much deeper question than you probably think. But if you don't mind a heavily simplified code example, here's a simulation of stringstream:

Yea... Didn't understand much of that...

Are you asking how it does the conversion, or how to use the class for that purpose? Because your code suggests you already understand the latter well enough to write something functional.

How it does the conversion.

If you are using VC++ 2010 Express on MS-Windows you can step through the >> operator and find out for yourself how M$ implemented it. I tried it, and its very complicated. But have a go at it yourself if you are really interested in the internals of the >> operator.

The simplest way to convert a string of digits to binary integer is to just convert each character by subtracting '0' from the digit.

Yea... Didn't understand much of that...

If you understood it, you wouldn't have asked how stringstreams work. Figure it out and you'll learn something. I'm not going to spoon feed you everything, but I'll answer any specific questions you have.

How it does the conversion.

Deep down it does the conversion much like atoi, the implementation of which is a very common beginner's exercise. Might I suggest googling it?

commented: Well said +17
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.