Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

stringstream >> operator

I have this code:

    std::string s = "\n\n\n\n+\n\n\n+";
    std::stringstream serializedDataStream(s);

    std::string plusCharacter, plusCharacter2;
    serializedDataStream >> plusCharacter ;
    cout << "plusCharacter "<<plusCharacter << "\n";
    serializedDataStream >> plusCharacter2 ;
    cout << "plusCharacter "<<plusCharacter2;

    //OUTPUT:
    //    plusCharacter +
    //    plusCharacter +

which means that the stringsteam >> operator skipped new lines. I looked into the std::stringstream documentation but I couldn't find an explanation for why this is happening. Is this a compiler specific behavior, or can I rely on this?

like image 750
Kam Avatar asked Dec 21 '12 16:12

Kam


2 Answers

This occurs because operator>> behaves as a formatted input function. Part of the process of a formatted input function is:

Each formatted input function begins execution by constructing an object of class sentry with the noskipws (second) argument false.

When noskipws is set to false (and the skipws flag on the stream being true, which is default), the sentry object "extracts and discards each character as long as the next available input character c is a whitespace character."

If you want to read each line at a time, use std::getline. This function behaves as an unformatted input function which has noskipws set to true and reads a line of text (as defined by the line terminator (parameter 3 of std::getline() (which defaults to '\n'))).

like image 174
Joseph Mansfield Avatar answered Oct 22 '22 00:10

Joseph Mansfield


Read up here.

Behaves as an FormattedInputFunction. After constructing and checking the sentry object, which may skip leading whitespace, extracts successive characters and stores them at successive locations of a character array whose first element is pointed to by s.

So as per the standard, it will toddle along whatever is in the stream until it actually finds something interesting, read that back to you, then stop. Then do the same again next time.

std::getline on the other hand will read everything up to the next newline character (this will be pulled off the stream but not given back to you) and gives it all back to you in a std::string. It is then up to you to get what you want (e.g. a number) from that string.

Edit: I'm struggling to find exactly which characters are considered to be whitespace by the default locale. I think it will be the same as defined for isspace (inherited from c), which are space (0x20), form feed (0x0c), line feed (0x0a), carriage return (0x0d), horizontal tab (0x09) and vertical tab (0x0b). But I haven't been able to convince myself 100% it is the same in this case. I'm not good with locales.

like image 2
BoBTFish Avatar answered Oct 21 '22 23:10

BoBTFish