简体   繁体   中英

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?

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'))).

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 (eg 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM