初识io流条件状态
eofbit 已到达文件尾
failbit 非致命的输入/输出错误,可挽回
badbit 致命的输入/输出错误,无法挽回
这三个标志位均用一位二进制位来表示,0表示清除,1表示设置。
对于eofbit,failbit,badbit。0表示正常,1表示被设置。
这三个整体构成了流的状态。若三个均为0,表示流状态正常,反之,若有一个为1,流状态非正常。包括达到了文件尾,出现可恢复性错误,出现了不可恢复性的错误。
另外还有一个标志位goodbit用来测试流状态是否正常。如果流状态正常返回true,输出1.否则输出0。
相对应与这四个标志位有四个函数分别用来测试相应的标志位的状态。他们分别为:
bool bad();
bool eof();
bool fail();
bool good();
看上去这四个函数的返回值是bool类型,返回值应该是true和false,也就是在我们C++里,0代表false,非0代表true,但是,在我们输出他们的结果时,得到的是0和1.不是true和false,也不是0和非0值。
二 测试流状态。
对于流状态的测试我们有三种方法。
1 rdstate()函数
我们可以用这个函数来返回当前的流状态。若我们用该函数输出当前流的状态信息,他输出的并不是一个二进制数。他输出的是一个十进制。是将二进制转换为对应的十进制后输出的。我们可以写个小程序进行一下测试,我们可以测试输入流的状态,也可以测试输出流的状态。
如:
#include <iostream>
using namespace std;
int main()
{
cout << "hello" << endl;
cout << cout.rdstate() << endl;//输出当前的流状态
if(cout.rdstate() == ios::goodbit)
{
cout<<"输出数据的类型正确,无错误!"<<endl;
}
if(cout.rdstate() == ios_base::failbit)
{
cout<<"输出数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;
}
system("pause");
return 0;
}
输出的当前的流状态为0. 表示当前流状态正常,那么他就和我们的if条件判断语句中的 第一个相匹配了。由此可知,rdstate() 返回的是eofbit,failbit,badbit三个标志的值,即返回的是一个strm::iostate类型。
2 我们可以用三个标志位对应的函数来测试当前的流状态。
如:
#include <iostream>
using namespace std;
int main()
{
cout << "你好吗?" << endl;
cout << cout.eof() << cout.fail() << cout.bad() << endl;
cout << cout.good() << endl;
return 0;
}
输出结果为:
你好吗?
000
1
前面的000表示三个标志位对应的值,均为0,由此可知此时流状态正常,故goodbit标志位被设置。所以good()函数输出结果为1.
3 用流本身来测试
如:
if (cin)
while (cin >> word)
if语句直接检查流的状态,while语句则检测表达式的返回值,即间接的检查流状态。
我们可以用如下的函数进行测试:
#include <iostream>
using namespace std;
int main()
{
int i;
cin >> i;
if (cin)
{
cout << "流状态正常" << i << endl;
}
else
{
cout << "流状态不正常" << i << endl;
}
return 0;
}
当我们输入的值为整型值或是能隐式转换成整型值时,当前输入流状态有效,若我们输入了字符串类型值,则会使当前输入流状态无效。
同样我们也可以对while语句进行测试。
#include <iostream>
using namespace std;
int main()
{
int i;
while(cin >> i)
{
cout << "当前输入流状态有效" << endl;
}
cout << "输入流状态无效" << endl;
return 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 |
using namespace std;
int main()
{
cout << ios:: failbit << endl;
cout << ios:: badbit << endl;
cout << ios:: eofbit << endl;
cout << ios:: goodbit << endl;
return 0;
}
四 设置流状态
1 设置流状态函数我们可以用setstate(flag)函数.参数为一个strm::iostate类型的值。
如: cin.setstate(ios::eofbit);
注意,它的目的并不是将流状态ios::eofbit替换(或覆盖)当前的输入流状态。而是仅仅的将标志位eofbit置1,其他位保持不变。
好的,既然设置好了。我们可以来查看一下我们的流状态是否设置成功了:
#include <iostream>
using namespace std;
int main()
{
cout << "输入流设置前的状态: " << endl;
cout << cin.bad() << cin.fail() << cin.eof() << endl;
cin.setstate(ios::failbit);
cout << "输入流设置后的状态: " << endl;
cout << cin.bad() << cin.fail() << cin.eof() << endl;
return 0;
}
然后我们再进行一下测试,看一下函数setstate是否覆盖我们原来的状态:
我们还用上一个函数,加点语句。
#include <iostream>
using namespace std;
int main()
{
cout << "输入流设置前的状态: " << endl;
cout << cin.bad() << cin.fail() << cin.eof() << endl;
cin.setstate(ios::failbit);
cout << "输入流设置第一次后的状态: " << endl;
cout << cin.bad() << cin.fail() << cin.eof() << endl;
cin.setstate(ios::badbit);
cout << "输入流设置第二次后的状态: " << endl;
cout << cin.bad() << cin.fail() << cin.eof() << endl;
return 0;
}
输出结果为:
000
010
110
由此可知,函数setstate函数并没有覆盖我们原来的流状态,而是仅仅的设置了对应位。
2 当我们设置了ios::failbit,ios::eofbit,ios::badbit流状态后,由于该三种状态为非正常状态,故设置后,对应的输入流或是输出流就处于无效状态,我们此后对于该流的任何使用均为无效,不起作用。
不妨我们来测试一下:
#include <iostream>
using namespace std;
int main()
{
cin.setstate(ios::failbit);
int i;
cin >> i;
cout << "hello!" << endl;
return 0;
}
上面这个程序不等待我们输入直接就输出了结果hello!由此可知,cin状态在设置后已处于无效状态,所有对此的操作均为视为透明的,或是无效的,直接跳过。那我们如何将流状态重置为有效呢,我认为有三种方法:
①:我们可以用函数clear();将流的所有状态重设为有效状态。
②:我们可以用函数clear(flag);
flag 可选值有ios::badbit ios::failbit ios::eofbit,这里参数的意思是重设对应的标志位有效。
③:我们可以用函数setstate(ios::goodbit);重设流有效状态
但经我在VC++ 6.0,VC++ 2008上测试后两种方法虽能成功运行,但并没起到作用。第一种方法可以。
#include <iostream>
using namespace std;
int main()
{
cin.setstate(ios::failbit);
cin.clear();
int i;
cin >> i;
cout << "hello!" << endl;
return 0;
}
输入流重为有效状态
此题的while循环的判断调件是,只要没有遇到文件结束符,不管输入流是否有效均执行循环体。
。下面我们再来整体看一个函数:
#include <iostream>
using namespace std;
int main()
{
int i;
while (cin >> i,!cin.eof())
{
try
{
if (cin.bad()) //出现系统故障
{
throw runtime_error("输入输出流出现故障"); //抛出异常
}
}
catch(runtime_error err) //处理异常
{
cout << err.what() << endl; //输出异常原因
cout << "try again?y/n" << endl;
char c;
cin >> c;
if ('y' == c)
{
continue;
}
else
{
break;
}
}
if (cin.fail()) //出现了可恢复错误
{
cerr << "bad data, try again";
cin.clear(); //重置输入流有效
cin.ignore(20,' '); //忽略20个输入字符。若不写此语句将陷入死循环。
continue;
}
cout << i << " ";
}
return 0;
}
此题的while循环的判断调件是,只要没有遇到文件结束符,不管输入流是否有效均执行循环体。
初识io流条件状态的更多相关文章
- 初识IO流之小型资源管理器
初次接触到IO流,根据书本上的知识,加上自己的摸索,发现了一些好玩的事情.(书本上的知识或多或少,有时候不足以解决我们的问题!这时候我们就应该自己去求解!!! 所以我们学习的时候要抱有探索的精神,求知 ...
- Java学习 · 初识 IO流
IO流 1. 原理与概念 a) 流 i. 流动,流向 ii. 从一端移动到另一端 源头到目的地 iii. 抽象.动态概念,是一连 ...
- 初识IO流
输入输出流,用来进行设备之间的数据传输. 是我们IO传输的数据是以文件的形式体现的,所以Java给我们提供了一个类,Flie用来描文件和目录 File(File parent, String chil ...
- ca73a_c++_流的条件状态
/*ca73a_c++_流的条件状态strm::iostate strm::badbit //流的状态strm::failbit //输入的状态,应该输入数字,结果输入为字符,strm::eofbit ...
- 从零开始学C++之IO流类库(二):文件流(fstream, ifstream, ofstream)的打开关闭、流状态
一.文件流 ofstream,由ostream派生而来,用于写文件 ifstream,由istream派生而来, 用于读文件 fstream,由iostream派生而来,用于读写文件 二.打开文件 说 ...
- 关于Java中面向对象章节、IO 流中的重点基础知识。
一.面向对象的三大特征,以及作用. 答:面向对象的三大特征即,封装性.继承性.多态性. 其分别的作用为 : 封装作用:将数据封装起来,提高数据的安全性, 继承作用:提高代码的复用性,减少冗余代码. 多 ...
- java IO流 对文件操作的代码集合
Io流 按照分类 有两种分类 流向方向: 有输入流和输出流 按照操作类型有:字节流和字符流 按照流向方向 字节流的一些操作 //读文件 FileInputStream fis = new FileIn ...
- C++ IO流小结
撒花庆祝下,终于看完了(C++Primer)第一部分,即将进入第二部分! IO部分,最基本的是iostream(istream.ostream),子类有fstream(ifstream.ofstrea ...
- IO流C++
1.iostream处理控制台IO #include<iostream> #include<string> using namespace std; istream& ...
随机推荐
- JQuery在页面中添加和除移DOM
1.before():将新节点添加到前面 2.after():将节点添加到低部 3.prepend():把节点变成第一个节点 4.append():把新节点添加到末端,与appendTo()效果相同, ...
- 玄机宝盒v1.6.1.1
最新版本:玄机宝盒v1.6.1.1 玄机宝盒v1.6.1.1 04-14/2016 给你的将是无与伦比的体验http://bbs.msdn5.com/thread-15-1-1.html(出处: 玄机 ...
- oracle 外部表
CREATE TABLE "EXT_ENTRY_WORKFLOW" ( ), ), "CREATE_DATE" DATE, ), ), ), ), ), ), ...
- Javascript Array.prototype.some()
当我们使用数组时,查找数组中包含某个特殊的项是非常常见的动作.下面例子是一个简单的实现: 01 planets = [ 02 "mercury", 03 " ...
- Objective-C的内省(Introspection)小结
内省(Introspection)是面向对象语言和环境的一个强大特性,Objective-C和Cocoa在这个方面尤其的丰富.内省是对象揭示自己作为一个运行时对象的详细信息的一种能力.这些详细信息包括 ...
- IIS本地服务器,设置IP地址问题
IIS启动本地网站的时候,设置了IP地址为本地IP,并绑定特定的端口号,电脑无法打开,但是同个局域网的手机可以打开.
- tomcat 7 用mod_jk做 负载均衡
在Win7中使用apache为tomcat做负载均衡,各组件及版本如下: 两个tomcat v 7.0.57 一个apache v 2.2.14 一个mod_jk v 1.2.33(for windo ...
- 常见的装置与其在Linux当中的档名
需要特别留意的是硬盘机(不论是IDE/SCSI/U盘都一样),每个磁碟机的磁盘分区(partition)不同时, 其磁碟档名还会改变呢!下一小节我们会介绍磁盘分区的相关概念啦!需要特别注意的是磁带机的 ...
- Highcharts-3.0.6
Highcharts-3.0.6 报表插件
- c++ void,内存操作函数
void的含义 void的字面意思是“无类型”, void * 则为“无类型指针”, void * 可以指向任何类型的数据 void几乎只有“注释”和限制程序的作用,因为从来没有人会定义一个void变 ...