io_state 输入状态标志及检测函数、设置函数
2006-08-18 00:45
288 查看
C++中负责的输入/输出的系统包括了关于每一个输入/输出操作的结果的记录信息。这些当前的状态信息被包含在io_state类型的对象中。io_state是一个枚举类型(就像open_mode一样),以下便是它包含的值。
goodbit 无错误
Eofbit 已到达文件尾
failbit 非致命的输入/输出错误,可挽回
badbit 致命的输入/输出错误,无法挽回
这四个标记位均为bit位,标记值为0或者1,每个标记位0表示清除,1表示设置。
其中failbit,badbit,Eofbit组成了流状态。
当这3个标记位都设置为0,则流状态正常,3个标记位某一个或几个设置为1时,流状态出现相应的问题。
而goodbit这个标记位是另一种流状态的表示方法:
当failbit,badbit,Eofbit这3个标记位都为0,即流状态无异常,goodbit标记位为1,表示流状态正常
当failbit,badbit,Eofbit这3个标记位任何一个为1,即流状态有异常,goodbit标记位为0,表示流状态非正常
goodbit含义为:流状态正常 标记位。该位设置为1,表示流状态正常,为0则流状态非正常。
1表示肯定,0表示否定,再结合标记位的名称,即可得出标记位当前状态的含义。
再来看看输入状态标记位、状态测试函数、状态设置函数之间的关系:
输入状态标记位常量有以下几个:
标记位常量
下面来解释这张表格:
ios::failbit ios::badbit ios::eofbit ios::goodbit均为常量,它们任何一个都代表了一种流状态,因此称为“输入状态标记位常量”。
比如,ios::failbit表示的是流状态为
流的failbit标记位值为1,eofbit标记位值为0,badbit标记位的值为0。
始终牢记:failbit,badbit,Eofbit组成了流状态
注意:它们不是failbit、badbit、eofbit、goodbit这四个标记位的存贮变量。
我们可以用输出语句来验证:
cout << ios:: failbit << endl;
cout << ios:: eofbit << endl;
cout << ios:: badbit << endl;
cout << ios:: goodbit << endl;
输出的结果为:
4
2
1
0
同样是将3个标记位视为二进制数转化为十进制的原理。
下面分析clear()函数:
cin.clear(ios::failbit);
使得cin的流状态将按照ios::failbit所描述的样子进行设置:failbit标记位为1,eofbit标记位为0,badbit标记位为0。无需担心goodbit标记位,failbit、eofbit、badbit任何一个为1,则goodbit为0。(goodbit是另一种流状态的表示方法)
cin.clear(ios::goodbit);
使得cin的流状态将按照ios::goodbit所描述的样子进行设置:failbit标记位为0,eofbit标记位为0,badbit标记位为0。此时goodbit标记位为1,从另一个角度表示cin的流状态正常。
因此clear() 函数作用是:将流状态设置成括号内参数所代表的状态,强制覆盖掉流的原状态。
再来分析一下setstate()函数:
与clear()函数不同,setstate()函数并不强制覆盖流的原状态,而是将括号内参数所代表的状态叠加到原始状态上。
比如,假设cin流状态初始正常:
cin.setstate (ios::failbit); //在cin流的原状态的基础上将failbit标记位置为1
cin.setstate (ios::eofbit); //在上一步结束的基础上,将cin流状态的eofbit标记位置为1
两条语句结束后,cin的faibit标记位和eofbit标记位均为1,badbit标记位为0
对比clear()函数的效果:
cin.clear (ios::failbit); //将cin的流状态置为ios::failbit所描述的状态
cin.clear (ios::eofbit); //将cin的流状态置为ios::eofbit所描述的状态
两条语句结束后,cin的eofbit标记位为1,而failbit标记位和badbit标记位为0
即使两种情况,在执行完各自的第一条语句后,cin的流状态情况相同,但当执行完第二条语句,本质区别就显露出来。
最后来看看如何利用rdstate()函数和输入状态标记位常量来判断输入流的状态:
#include <iostream>
using namespace std;
int main()
{
int a;
cin>>a;
cout<<cin.rdstate()<<endl;
if(cin.rdstate() == ios::goodbit)
{
cout<<"输入数据的类型正确,无错误!"<<endl;
}
if(cin.rdstate() == ios::failbit)
{
cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;
}
system("pause");
return 0;
}
利用前面所讲的rdstate() 函数返回值原理和输入状态标记位常量表,不难理解:
rdstate() 函数返回当前流对象的failbit、eofbit、badbit3个标记位状态的十进制值
输入状态格式常量也是failbit、eofbit、badbit3个标记位状态的十进制值
比如cin流状态读取错误,即failbit标记位为1,eofbit标记位为0,badbit标记位为0,则:
cin.rdstate()的返回值为4,而格式常量ios::failbit的十进制也是4
因此,if(cin.rdstate() == ios::failbit) 判断为Ture
因此程序当中的两个if语句能有效识别出流状态
再来看看有些许不同的程序:
#include <iostream>
using namespace std;
int main()
{
cin.setstate(ios::failbit);
cin.setstate(ios::eofbit);
cout<<cin.rdstate()<<endl;
if(cin.rdstate() == ios::goodbit)
{
cout<<"输入数据的类型正确,无错误!"<<endl;
}
if(cin.rdstate() == ios::failbit)
{
cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;
}
system("pause");
return 0;
}
输出结果为:
6
请按任意键继续...
原因为何?
cin流状态被设置成failbit标记位置为1,eofbit标记位置为1,badbit标记位为0
那么cin.rdstate()的返回值二进制为110,十进制为6,即输出6。
参照输入状态标记位常量表:
ios::goodbit的二进制为000,十进制为0,因此if(cin.rdstate() == ios::goodbit)判断为False
ios::failbit的二进制为100,十进制为4,因此if(cin.rdstate() == ios::failbit)判断为False
然后system("pause"); 语句使得输出 请按任意键继续...
很有意思吧,cin对象明明failbit标记位为1,但表达式cin.rdstate() == ios::failbit却是False,这就是原因。
rdstate()函数与输入状态标记位常量的对比是严格按照数值对比的。
另外:关于cin对象,输入内容与接受的变量 完全匹配,部分匹配,完全不匹配的各种情况下,标记位将会如何变化,请参考http://blog.csdn.net/ygj149078299/archive/2005/11/29/538998.aspx
不对之处,敬请指教。
goodbit 无错误
Eofbit 已到达文件尾
failbit 非致命的输入/输出错误,可挽回
badbit 致命的输入/输出错误,无法挽回
这四个标记位均为bit位,标记值为0或者1,每个标记位0表示清除,1表示设置。
其中failbit,badbit,Eofbit组成了流状态。
当这3个标记位都设置为0,则流状态正常,3个标记位某一个或几个设置为1时,流状态出现相应的问题。
而goodbit这个标记位是另一种流状态的表示方法:
当failbit,badbit,Eofbit这3个标记位都为0,即流状态无异常,goodbit标记位为1,表示流状态正常
当failbit,badbit,Eofbit这3个标记位任何一个为1,即流状态有异常,goodbit标记位为0,表示流状态非正常
goodbit含义为:流状态正常 标记位。该位设置为1,表示流状态正常,为0则流状态非正常。
1表示肯定,0表示否定,再结合标记位的名称,即可得出标记位当前状态的含义。
bool fail();
bool eof();
bool bad();
bool good();
这四个函数分别测试相应的标记位,如果标记位被设置,则相应的测试函数返回True。
如果将函数返回值进行输出,输出的并非Ture或者False,而是1或者0。
那么,这就表示如果测试函数的结果输出为1,表示对应的标记位被设置。
比如,假设failbit被设置了(failbit值为1),则流状态出现了“fail”,即流状态异常,那么:
输入流将关闭,即cin不能再工作,且goodbit的值变为1。
而:
cout << cin.fail() << cin.eof() << cin.bad();
的输出为:
100
下面来看看rdstate()函数:
rdstate()函数会返回当前的流状态。
还记得吗?流状态有两种表示方法:
1、failbit,badbit,Eofbit组成了流状态
2、goodbit这个标记位是另一种流状态的表示方法
rdstate()函数会用哪种流状态表示方法得出返回值?
答案是第一种,也就是说,rdstate()函数会返回流状态的详细情况。
如果将rdstate()函数的返回值进行输出,输出结果是一个十进制数,而不是failbit,Eofbit,badbit这3个标记位各自的当前值,为什么?
比如,仍然假设failbit被设置了,则:
cout << cin.rdstate();
的输出为:
4
为什么?
实际上,failbit,Eofbit,badbit这3个标志位的bit值可以视为一个整体,从而以一个二进制数的形式转化为十进制数。
rdstate()函数返回的是流状态的详细情况,因此,将3个标记位的状态值视为一个整体进行输出。
注意到了吗?二进制数100转化为十进制就是4
3个标志位的bit位顺序是:
failbit Eofbit badbit
接着看看输入对象是如何利用标记位状态的,以cin对象为例:
对于if (cin)这样的判断来说:
首先,cin将检测自己的状态是否正常。
当goodbit这个标记位为1时,即good()函数返回值为1,(或者说rdstate()函数返回值为0时),cin的值为True,可以工作。
当goodbit这个标记位为0时,即good()函数返回值为0,(或者说rdstate()函数返回值非0时),cin的值为False,不可以工作。
然后,if语句根据cin的值进行判断。
记住:goodbit标记位为1时,是对其标记名称的肯定;而为0时,是对其标记名称的否定
再来看看输入状态标记位、状态测试函数、状态设置函数之间的关系:
输入状态标记位常量有以下几个:
常量 | 含义 | failbit标记位的值 | eofbit标记位的值 | badbit标记位的值 | 转化为10进制 |
ios::failbit | 输入(输出)流出现非致命错误,可挽回 | 1 | 0 | 0 | 4 |
ios::badbit | 输入(输出)流出现致命错误,不可挽回 | 0 | 0 | 1 | 2 |
ios::eofbit | 已经到达文件尾 | 0 | 1 | 0 | 1 |
ios::goodbit | 流状态完全正常 | 0 | 0 | 0 | 0 |
ios::failbit ios::badbit ios::eofbit ios::goodbit均为常量,它们任何一个都代表了一种流状态,因此称为“输入状态标记位常量”。
比如,ios::failbit表示的是流状态为
流的failbit标记位值为1,eofbit标记位值为0,badbit标记位的值为0。
始终牢记:failbit,badbit,Eofbit组成了流状态
注意:它们不是failbit、badbit、eofbit、goodbit这四个标记位的存贮变量。
我们可以用输出语句来验证:
cout << ios:: failbit << endl;
cout << ios:: eofbit << endl;
cout << ios:: badbit << endl;
cout << ios:: goodbit << endl;
输出的结果为:
4
2
1
0
同样是将3个标记位视为二进制数转化为十进制的原理。
下面分析clear()函数:
cin.clear(ios::failbit);
使得cin的流状态将按照ios::failbit所描述的样子进行设置:failbit标记位为1,eofbit标记位为0,badbit标记位为0。无需担心goodbit标记位,failbit、eofbit、badbit任何一个为1,则goodbit为0。(goodbit是另一种流状态的表示方法)
cin.clear(ios::goodbit);
使得cin的流状态将按照ios::goodbit所描述的样子进行设置:failbit标记位为0,eofbit标记位为0,badbit标记位为0。此时goodbit标记位为1,从另一个角度表示cin的流状态正常。
因此clear() 函数作用是:将流状态设置成括号内参数所代表的状态,强制覆盖掉流的原状态。
再来分析一下setstate()函数:
与clear()函数不同,setstate()函数并不强制覆盖流的原状态,而是将括号内参数所代表的状态叠加到原始状态上。
比如,假设cin流状态初始正常:
cin.setstate (ios::failbit); //在cin流的原状态的基础上将failbit标记位置为1
cin.setstate (ios::eofbit); //在上一步结束的基础上,将cin流状态的eofbit标记位置为1
两条语句结束后,cin的faibit标记位和eofbit标记位均为1,badbit标记位为0
对比clear()函数的效果:
cin.clear (ios::failbit); //将cin的流状态置为ios::failbit所描述的状态
cin.clear (ios::eofbit); //将cin的流状态置为ios::eofbit所描述的状态
两条语句结束后,cin的eofbit标记位为1,而failbit标记位和badbit标记位为0
即使两种情况,在执行完各自的第一条语句后,cin的流状态情况相同,但当执行完第二条语句,本质区别就显露出来。
最后来看看如何利用rdstate()函数和输入状态标记位常量来判断输入流的状态:
#include <iostream>
using namespace std;
int main()
{
int a;
cin>>a;
cout<<cin.rdstate()<<endl;
if(cin.rdstate() == ios::goodbit)
{
cout<<"输入数据的类型正确,无错误!"<<endl;
}
if(cin.rdstate() == ios::failbit)
{
cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;
}
system("pause");
return 0;
}
利用前面所讲的rdstate() 函数返回值原理和输入状态标记位常量表,不难理解:
rdstate() 函数返回当前流对象的failbit、eofbit、badbit3个标记位状态的十进制值
输入状态格式常量也是failbit、eofbit、badbit3个标记位状态的十进制值
比如cin流状态读取错误,即failbit标记位为1,eofbit标记位为0,badbit标记位为0,则:
cin.rdstate()的返回值为4,而格式常量ios::failbit的十进制也是4
因此,if(cin.rdstate() == ios::failbit) 判断为Ture
因此程序当中的两个if语句能有效识别出流状态
再来看看有些许不同的程序:
#include <iostream>
using namespace std;
int main()
{
cin.setstate(ios::failbit);
cin.setstate(ios::eofbit);
cout<<cin.rdstate()<<endl;
if(cin.rdstate() == ios::goodbit)
{
cout<<"输入数据的类型正确,无错误!"<<endl;
}
if(cin.rdstate() == ios::failbit)
{
cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;
}
system("pause");
return 0;
}
输出结果为:
6
请按任意键继续...
原因为何?
cin流状态被设置成failbit标记位置为1,eofbit标记位置为1,badbit标记位为0
那么cin.rdstate()的返回值二进制为110,十进制为6,即输出6。
参照输入状态标记位常量表:
ios::goodbit的二进制为000,十进制为0,因此if(cin.rdstate() == ios::goodbit)判断为False
ios::failbit的二进制为100,十进制为4,因此if(cin.rdstate() == ios::failbit)判断为False
然后system("pause"); 语句使得输出 请按任意键继续...
很有意思吧,cin对象明明failbit标记位为1,但表达式cin.rdstate() == ios::failbit却是False,这就是原因。
rdstate()函数与输入状态标记位常量的对比是严格按照数值对比的。
另外:关于cin对象,输入内容与接受的变量 完全匹配,部分匹配,完全不匹配的各种情况下,标记位将会如何变化,请参考http://blog.csdn.net/ygj149078299/archive/2005/11/29/538998.aspx
不对之处,敬请指教。
相关文章推荐
- QT QdateEdit设置不可输入,用到findchild()或者findchildren和dumpObjectTree()函数
- io_state 状态标志 缓冲区
- 文件操作,及文件操作时的权限设置,快速实现文件拷贝,C语言常用IO函数
- 2 curses库IO处理--输入/输出函数
- 第七篇:使用 fcntl 函数 获取,设置文件的状态标志
- windows环境编程: 线程创建函数 设置线程名 隐藏DOS窗口 重定向IO
- 写一个函数,检测输入的数字旋转180度后是否相等,比如619旋转后还是619.
- 2 curses库IO处理--输入/输出函数
- 输入输出格式标记位、格式常量、格式设置函数
- react native 学习笔记 2016_1223 (环境,箭头函数,state设置,图片使用等)
- PHP的isset()函数 一般用来检测变量是否设置
- 输入输出格式标记位、格式常量、格式设置函数
- 请求验证过程检测到有潜在危险的客户端输入值,对请求的处理已经中止。该值可能指示存在危及应用程序安全的尝试,如跨站点脚本攻击。若要允许页面重写应用程序请求验证设置
- 使用 fcntl 函数 获取,设置文件的状态标志
- PHP的isset()函数 一般用来检测变量是否设置
- c8051f340当io脚设为数字输入时设置需要注意
- 2013华为实习生上机考试试题(一)华为机试 请设计函数int getTest(char input[]) ,检测输入字符串中是否包含连续的或者离散的test,test只出现一次
- read( ) 函数 —— 终端输入设备的阻塞与非阻塞的设置
- 检测变量是否已经设置,并比较Empty 和Isset 两个函数的区别
- C++中的文件输入/输出(4):检测输入/输出的状态标志