The role of std::ws (whitespace) when reading data

丶灬走出姿态 提交于 2019-12-06 04:57:41

The primary use of std::ws is when switching between formatted and unformatted input:

  • formatted input, i.e., the usual input operators using `in >> value, skip leading whitespace and stop whenever the format is filled
  • unformatted input, e.g., std::getline(in, value) does not skip leading whitespace

For example, when reading an age and a fullname you might be tempted to read it like this:

 int         age(0);
 std::string fullname;
 if (std::cin >> age && std::getline(std::cin, fullname)) { // BEWARE: this is NOT a Good Idea!
     std::cout << "age=" << age << "  fullname='" << fullname << "'\n";
 }

However, if I'd enter this information using

47
Dietmar Kühl

It would print something like this

age=47 fullname=''

The problem is that the newline following the 47 is still present and immediately fills the std::getine() request. As a result you'd rather use this statement to read the data

if (std::cin >> age && std::getline(std::cin >> std::ws, fullname)) {
    ...
}

The use of std::cin >> std::ws skips the whitespace, in particular the newline, and carries on reading where the actual content is entered.

By default, the stream's skipws bit is set and whitespace is automatically skipped before each input. If you unset it with iss >> std::noskipws, then you'll need iss >> std::ws later.

There are also times when whitespace is not automatically skipped. For example, to detect the end of the input, you can use if ( ( iss >> std::ws ).eof() ).

skipws and noskipws are sticky but ws is NOT sticky, so if you want to skip whitespaces with ws you must use it before every operator>>.

Also note that skipws and noskipws only apply to formatted input operation performed with operator>> on the stream. but ws applies to both formatted input operation ( using operator>> ) and unformatted input operation (e.g. get, put, putback , .... )

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

int main ()
{
    char c;
    istringstream input( "     1test      2test       " );

    input >> skipws;
    c = input.peek();
    //skipws doesn't skip whitespaces in unformatted input
    cout << "After using skipws c = " << c << endl;

    input >> ws;
    c = input.peek();
    cout << "After using ws c = " <<  c << endl;
}

Output:

After using skipws c =  
After using ws c = 1
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!