1

For example:

#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main() {
    int num = 10;
    string str;
    stringstream toString;
    toString << num;
    toString >> str;
    cout << str << "\n"; //10

    int num2 = 20;
    string str2;
    toString << num2;
    toString >> str2;
    cout << str2 << "\n"; //str2 is empty
    return 0;
}

I know that I must clear this like:

toString.str("");
toString.clear();

But why doesn't it clear automatically after using operator >>?

lrineau
  • 6,036
  • 3
  • 34
  • 47
ratojakuf
  • 708
  • 1
  • 11
  • 21

2 Answers2

6

If I do toString >> a >> b >> c and the first one fails, I don't want the flag to be cleared so that the final state appears to have succeeded.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
1

After the first read toString >> str;. then the rdstate() of toString is std::ios_base::eofbit, because during the reading of str the end of the string has been reached.

Then the line toString << num2; does not modify the string stored in toString but sets the failbit of toString. That is the standard behavior of all formatted output.

The line toString >> str2; does nothing: the failbit is already set, and no reading is performed: str2 stays empty.

The clear() function resets the rdstate() of toString to std::ios_base::goodbit.

The reasons why the >> must not call clear() are:

  1. in case there is an error, then one must be able to test it using the functions bad(), fail(), eof() (or rdstate() directly),
  2. and one can use the operator >> several times:

    #include <iostream>
    #include <sstream>
    
    int main() {
      std::stringstream sstr("10 20");
      int i, j;
      sstr >> i >> j;
      if(!sstr.fail()) {
        std::cout << i << " " << j << "\n";
        return 0;
      }
      return 1;
    }
    
lrineau
  • 6,036
  • 3
  • 34
  • 47