std::basic_ios::clear
void clear( std::ios_base::iostate state = std::ios_base::goodbit );
通过分配state 的值来设置流错误状态标志。默认情况下,分配std::ios_base::goodbit 具有清除所有错误状态标志的效果。
如果rdbuf() 是空指针(即没有关联的流缓冲区),则分配state | badbit。可能会抛出异常。
在这种情况下,设置位基本上意味着它将位设置为清除状态。
如果你不带参数调用clear,它会将所有位设置为清除状态,通过设置“goodbit”,这是与其他状态互斥的。如果您只标记某个位,则只会设置该位,清除其他位(以及好位)。无论如何,如上所述,如果在调用此方法期间流的输入缓冲区无效,则clear() 也将badbit 设置为true,因此方法good() 和operator bool 将返回false 和fail()仍将返回true。
也就是说,为什么需要清除这些位但保持错误状态取决于进一步的代码,通常是能够检测到发生的错误,但能够从流中请求更多数据(请求正确的输入?)
#include <iostream>
#include <limits>
#include <string>
int main() {
using std::cout;
using std::cin;
int a;
do
{
cout << " Please enter an integer number:";
cin.clear();
cin >> a;
if(cin.fail())
{
cout << "Error occured while parsing input.\n";
cin.clear(std::istream::failbit);
}
// do something
if(cin.fail())
{
std::string str;
//now clear everything, to unlock the input.
cin.clear();
cin >> str;
cout << "Wrong input was: " << str << "\n";
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// setting fail bit again, so loop will go on
cin.clear(std::istream::failbit);
}
} while(cin.fail());
cout << "Thank you!";
}
如果不调用::clear(std::istream::failbit) 和::ignore,循环将永远工作,因为标志和缓冲区的状态会强制尝试一遍又一遍地解析相同的缓冲区内容。实际上,您可能会尝试重新解析它,例如读取字符串并打印。只调用clear() 就可以了,但是我们需要创建自己的标志来让我们做出正确的反应。
流的“状态”是std::ios_base::iostate 类型的私有字段,其值等于eofbit、badbit 和failbit 常量的二进制组合。 goodbit 常量等于零,表示无错误状态。提供对该字段的读写操作的两个访问器:
void setstate( iostate state );
iostate rdstate() const;
注意,setstate(state) 的作用是clear(rdstate() | state),也就是说如果clear 可以设置 iostate 的精确值,setstate 只能设置新的位为真,而不能清除已经设置的位。
int main()
{
std::ostringstream stream;
if (stream.rdstate() == std::ios_base::goodbit) {
std::cout << "stream state is goodbit\n";
}
stream.setstate(std::ios_base::eofbit);
// check state is exactly eofbit (no failbit and no badbit)
if (stream.rdstate() == std::ios_base::eofbit) {
std::cout << "stream state is eofbit\n";
}
}
每个位都有访问器:fail()、bad()、eof()、good()。
本质上,fail() 在 (rdstate()|std::ios_base::failbit) != 0 时返回 true,依此类推(参见 30.5.5.4 basic_ios 标志函数,ISO/IEC 14882:2017,编程
语言——C++)
-
operator bool 已定义并返回 good()
-
operator! 已定义并返回 !good()
线
if (stream.rdstate() == std::ios_base::goodbit)
可以替换为
if (stream)
因为后者会导致上下文转换为bool。
与iostate 的位相关的效果(根据 ISO C++):
-
badbit 表示输入或输出序列的完整性丢失(例如文件中不可恢复的读取错误);
-
eofbit 表示输入操作到达了输入序列的末尾;
-
failbit 表示输入操作未能读取预期的字符,或者输出操作未能生成
所需的字符。