c++ setstate

imak47 2011-08-09 10:42:07
这些日子刚开始看C++primier,中间看到标准I/O库这一章的多种状态的处理,遇到了下面这句,请教哪位高人给解释一下这句到底是干什么用的呀。
原文如下:
// sets both the badbit and the failbit
is.setstate(ifstream::badbit | ifstream::failbit);

将对象 is 的 failbit 和 badbit 位同时打开。实参:

is.badbit | is.failbit

生成了一个值,其对应于 badbit 和 failbit 的位都打开了,也就是将这两个位都设置为 1,该值的其他位则都为 0。在调用 setstate 时,使用这个值来开启流条件状态成员中对应的 badbit 和 failbit 位。
...全文
188 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
imak47 2011-11-06
  • 打赏
  • 举报
回复
嗯,谢谢大家啊
qscool1987 2011-11-01
  • 打赏
  • 举报
回复
7#说的相当明白了 | 就是或运算 ,ifstream::badbit | ifstream::failbit就是把他们的2进制值进行或运算而已,计算出来的值表示拥有他们共同的属性,这在VC中很常见,例如表示窗口样式时,控件显示样式等等,至于ifstream::badbit | ifstream::failbit这样计算有没有什么用处,建议不做考虑,其实一点用也没有
sharelx 2011-11-01
  • 打赏
  • 举报
回复
我也遇到同样的问题,在编译器里试了一下,ifstream::badbit对应的二进制是100,ifstream::failbit的二进制是010,ifstream::eofbit的二进制是001。ifstream::badbit | ifstream::failbit即将state设置为110,也就是他上面说的同时打开了badbit和failbit位。不知道这个解释是否是楼主想要的?
imak47 2011-08-11
  • 打赏
  • 举报
回复
这个或运算我知道,就是不明白这个程序具体执行时有什么作用,执行
ifstream::badbit | ifstream::failbit
有什么用啊?
WarriorKing 2011-08-10
  • 打赏
  • 举报
回复
一. 面向对象的标准库
IO标准库类型和头文件
头文件
iostream istream从流中读取
ostream写到流中去
iostream对流进行读取;从istream和ostream派生而来
fstream ifstream从文件中读取
ofstream写到文件中去,由ostream派生而来
fstream读写文件,由iostream派生而来
sstream istringstream从string对象读取:由istream派生而来
ostreamstream写到string对象中去;由ostream派生而来
stringstream对string对象进行读写;由iostream派生而来
IO类型在三个独立的头文件中定义:iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,而sstream所定义的类型则用于读写存储在内存中的string对象。
对istream&进行操作的函数,也可使用ifstream或者istringstream对象来调用。类似的,形参为ostream&类型的函数也可用ofstream或者ostringstream对象调用。因为IO通过继承关联,所以可以只编写一个函数,而将他应用到三种类型的流上:控制台,磁盘文件或者字符串流。
1. 国际字符的支持
除了支持读写是由char类型组成的流外,标准库还定义了一组相关的类型,支持wchar_t类型。每个类都加上w,以此与char类型的版本区分开来。于是,wostream,wistream和wiostream可以从控制窗口读写wchat_t类型的数据。相应的文本输入输出类是wifstream,wofstream和wfstream。同样,wchar_t的读入类型是wcin,标准输出是wcout;而标准错误是wcerr。
2. IO对象不可赋值或复制
由于流对象不能复制,因此不能存储在vector或其他容器中。另外,形参或返回类型不能为流类型。如果需要传递或返回IO对象,则必须传递返回指向该对象的指针或引用。
一般情况下,如果需要对传递IO的对象进行读写,可用非const引用方式传递这个流对象。
二. 条件状态
IO标准库的条件状态
strm::iostate 机器相关的类型名,由各个iostream类定义,用于条件状态
strm::badbit strm::iostate类型的值,用于指出被破坏的流
strm::failbit strm::iostate类型的值,用于指出失败的IO操作
strm::eofbit strm::iostate类型的值,用于指出流已经达到文件结束符。
s.eof() 如果设置了流s的eofbit值,则该函数返回true。
s.fail() 如果设置了流s的failbit值,则返回true。
s.bad() 如果设置了流s的badbit值,则返回true。
s.good() 如果流s处于有效状态,则该函数返回ture。
s.clear() 将s中的所有状态值都重设为有效状态
s.clear(flag) 将流s中的某个指定条件状态设为有效。Flag的类型是
strm::iostate
s.setstate(flag) 给流s添加指定条件,flag的类型是strm::iostate
s.rdstate() 返回流s的当前条件,返回值类型为strm::iostate
流必须处于无错误状态,才能用于输入和输出。检查流是否可用的最简单方法是检查其真值:
if(cin)
//ok, 可以使用cin,它为合法值
while(cin>>word)
//ok.成功读取操作
1. 条件状态
所有流对象都包括一个条件状态成员,该成员分别有setstate和clear操作管理。这个状态成员为iostate类型。这是由各个iostream类分别定义的机器相关类型。该状态成员以二进制的形式使用。
badbit标志着系统级的故障,如无法恢复的读写错误。如果出现了这样的错误,则该流通常就不能在继续使用了。如果出现的是可恢复错误,此时则设置failbit标志,这种导致了failbit的问题是可以修正的。Eofbit实在遇到文件结束符设置的,此时同时还设置了failbit。
流的状态由bad,fail,eof和good操作表示。如果bad,fail或者eof任意一个为ture,则检查流本身将显示该流处于错误状态。类似的,如果这三个条件没有一个为true。则good操作将返回true。
2. 条件状态的访问
rdstate成员函数返回一个iostate类型的值,该值对应于流当前的整个条件状态。
istream::iostate old_state=cin.rdstate();
cin.clear();
process_input():
cin.clear(old_state):
3. 多种状态的处理
常常会出现设置或清楚多个二进制的情况。此时,可以通过多次调用setstate或者clear函数实现。另外一种方法则是安位或操作符来实现。
is.setstate(ifstream::badbit | ifstream::failbit);
三. 输出缓冲区的管理
每个IO对象管理一个缓冲区,用于存储程序读写的数据。
os<<" please enter a value: ";
系统将字符串字面值存储在与流os相关联的缓冲区中,下面几种情况将导致缓冲区的内容被刷新,即写入到真实的输出设备或者文件:
a. 程序正常结束。作为main函数返回工作的一部分,将清空所有输出缓冲区。
b. 在一些不确定到时候,缓冲区可能满了,缓冲区在写入下一个值之前刷新。
c. 用操作符显式的刷新缓冲区,例如行换行符endl。
d. 在每次输出操作执行完后,用unitbuf操作符设置流的内部状态,从而情况缓冲区。
e. 可将输入流和输出流关联起来,在这种情况下,在读输入流时将刷新其关联的输出缓冲区。
1. 输出缓冲区的刷新
除了endl操作符,C++还提供了另外的两个类似的操纵符。第一个是经常使用的flush,用于刷新流,但仍然不再输出中添加任何字符。第二个是比较少用的ends,这个操作在缓冲区中插入空字符null,然后刷新它。
2. unitbuf操纵符
如果需要刷新所有输出,最好使用unitbuf操作符。这个操作符在每次执行完写操作后都刷新流:
cout<< unitbuf <<"first"<<"second"<<nounitbuf;
nounitbuf操纵符将流恢复为正常的,由系统管理的缓冲区刷新方式。
如果程序崩溃了,则不会刷新缓冲区。如果程序不正常结束,输出缓冲区将不会被刷新。
3. 将输入和输出绑在一起
当输入流和输出流绑在一起时,任何读输入流的尝试都将首先刷新其输出流相关联的缓冲区。标准库将count和cin绑在一起。语句:cin>>ival;导致cout关联的缓冲区被刷新。交互式系统通常应确保它们的输入和输出流是绑在一起的。这样做意味着可以保证任何输出,包括给用户的提示,都在试图读之前输出。
Tie函数可以用istream或ostream对象调用,使用一个指向ostream对象的指针形参。调用tie函数时,将实参流绑在调用该函数的对象上,如果一个流调用tie函数将其本身绑定在传递给tie的ostream实参对象时,则该流上的任何IO操作都会被刷新实参所关联的缓冲区。
四. 文件的输入与输出
fstream头文件中定义了三种支持文件IO的类型:
a. ifstream,由istream派生而来。
b. ofstream,由ostream派生而来
c. fstream,由iostream派生而来
fstream类型除了继承下来的行为外,还定义了两个自己的新操作,open和close,以及形参为要打开的文件名的构造函数。fstream,ifstream,ofstreram对象可以调用这些操作,其他的IO类型不能调用。
1. 文件流对象的使用
有两种方式:
a.直接用带参数的够造函数打开一个文件名为string类型的ifile,
ifstream infile(ifile.c_str());
b.使用默认构造函数初始化一个文件流对象,然后调用open函数。
ifstream infile;
infile.open("in");
检查文件是否打开成功,这是一个好习惯:
if(!infile)
{
cerr<<"error: unable to open input file: "<<ifile<<endl;
return -1;
}
将文件流与新文件重新绑定
fstream对象一旦打开,就保持与指定文件相关联。如果要把fstream对象与另一个不同的文件关联,则必须先关闭现在的文件,然后打开另一个文件。
ifstream infile("in");
infile.close();
infile.open("next");
清除文件流的状态
关闭流不能改变流对象的内部状态。如果最后的读写操作失败了,对象的状态保持为错误模式,直到指向clear操作重新恢复流的状态为止。调用clear后,就像重新创建了个对象一样。如果程序员要重用文件流读写多个文件,必须在读另一个文件之前调用clear清除该流的状态。
2. 文件模式
in 打开文件做读操作
out 打开文件做写操作
app 在每次写之前找到文件尾
ate 打开文件后立即定位在文件尾
trunc 打开文件时清空已存在的文件流
binary 以二进制模式进行IO操作
out,trunk,和app模式只能用于指定与offstream或fstream对象关联的文件;in模式只能用于指定与ifstream或fstream对象相关联的文件。所有的文件都可以用ate或binary模式打开。Ate模式只有在打开时有效:文件打开后将定位在文件尾。以binary模式打开的流则将文件以字节的形式处理,不解释流中的字符。
默认时,与ifstream流对象关联的文件将以in模式打开,该模式运行文件做读的操作,与ofstream关联的文件则以out模式打开,使文件可写。从效果来看,为ofstream对象指定了out模式等效于同时指定了out和trunc模式。对于ofstream打开的文件,要保存文件中已存在的数据,唯一方法是显式的指定app模式打开。
a. 对同一文件做输入和输出运算
fstream对象既可读也可写它所关联的文件。Fstream如何使用它的文件取决于打开文件时指定的模式。默认情况下,fstream对象是以in和out模式同时打开。当文件同时以in和out打开时不清空。如果打开fstream所关联的文件时,只用out模式,而不用in模式,则文件清空已存在的数据,如果打开指定了trunc模式,无论是否同时指定了in模式,文件同样会被清空。
b. 模式是文件的属性而不是流属性
只要调用open函数,就要设置文件模式,其模式的设置可以是显式的,也可以是隐式的。如果没有指定文件模式,将使用默认值。
c. 打开模式的有效组合
out ; out | app ; out | trunc ; in ; in | out ; in | out | trunk;
五. 字符串流
istringstream,由istream派生而来,提供读string的功能
ostringstream 由ostream派生而来,提供写string的功能
stringstream 由iostream派生而来,提供读写string的功能
stringstream除了继承基类的操作外,还各自定义一个又string形参的构造函数,这个构造函数将string类型实参复制给stringstream对象。
stringstream特定的操作
stringsteam strm; 创建自由的stringstream对象
stringstream strm(s); 创建存储s的副本的stringstream对象,其中s是string类型的对象。
strm.str(); 返回strm中存储的string类型对象
strm.str(s); 返回string类型的s复制给strm,返回void。
1. stringstream对象的使用
将一个stringstream对象与所读取的行绑定起来,这样只需使用普通的string输入操作符即可读出每行中的单词。
String line, word;
While ( getline(cin, line))
{
istringstream stream(line);
while( stream>>word)
//….
}
2. stringstream提供的转换或格式化
stringstream对象的一个最常用的用法是:需要在多种数据类型之间实现自动格式化使用该类类型。
luciferisnotsatan 2011-08-10
  • 打赏
  • 举报
回复
就是个 位运算
WarriorKing 2011-08-10
  • 打赏
  • 举报
回复
这个我好久之前看过,不过现在没什么印象了,帮补了LZ
至善者善之敌 2011-08-10
  • 打赏
  • 举报
回复
位运算

| 是相或的意思

只要一方为1 ,即为1,否则为0
imak47 2011-08-10
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 luciferisnotsatan 的回复:]
就是个 位运算
[/Quote]那么这个位运算到底是怎么运算的,运算的结果又是什么,书上写的感觉理解不了啊

64,642

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧