问题
Data saved in my file is (white spaces added at both beginning and end on purpose for this test):
1 2 3
Loading the data using the code below with or without "std::ws" does not cause any difference. So I am confused by the role of "std::ws" as I have seen code using it. Can someone explain a little bit? Thanks!
void main ()
{
ifstream inf;
inf.open ("test.txt");
double x=0, y=0, z=0;
string line;
getline(inf, line);
istringstream iss(line);
//Using "std::ws" here does NOT cause any difference
if (!(iss >> std::ws >> x >> y >> z >> std::ws))
{
cout << "Format error in the line" << endl;
}
else
{
cout << x << y << z << endl;
}
iss.str(std::string ());
iss.clear();
cin.get();
}
回答1:
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.
回答2:
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() )
.
回答3:
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
来源:https://stackoverflow.com/questions/32365277/the-role-of-stdws-whitespace-when-reading-data