C++ Primer- 流的条件状态以及缓冲区管理
来源:互联网 发布:php 字符串大小写转换 编辑:程序博客网 时间:2024/05/16 09:02
IO标准库提供了一系列条件状态成员,用来标记IO对象是否处于可用状态。使用strm::iostate类型的值来表示条件状态,
这是一个跟机器有关的整型值,通过判断特定的一些位是否为1来判断流处于什么状态,有三个常量strm::badbit, strm::failbit, strm::eofbit 分别代表流被破坏,失败的IO操作和流已经到达文件尾。那么我们如何判断一个流比如说s处于什么状态呢,s.eof()若为true,表示到达文件尾,s.bad()若为ture,代表流被破坏,而 s.fail()若为true,则代表s遇到了失败的IO操作。
我们现在可以通过这三个函数来判断流的状态,那么下一步,该如何改变这个流的状态呢,有以下几个函数:
s.clear() 清除所有不可用的状态,重新使流有效
s.clear(flag) 设置流的某一个不可用状态,如badbit状态,所以flag是strm::iostate类型的
s.setstate(flag) 添加流的某一个不可用状态,如failbit状态,同样是strm::iostate类型值
s.rdstate() 返回流的当前状态,是strm::iostate类型值
这里我们通过一个例子来练习使用流的条件状态,题目是C++ Primer 练习8.3原题:
编写一个函数,唯一形参和返回值都是istream&类型,该函数一直读取流直到到达文件结束符,同时把读到的内容输出到标准输出中,最后,重设流使其有效并返回,通过cin为实参实现调用来测试该函数。
代码和注释如下:
/*** @file main.cpp* @brief 编写一个函数,可以一直读取流直到文件结束 并输出* @details* @author jason.mrbourne@gmail.com* @date 2014-5-20*/#include <iostream>#include <stdexcept>using namespace std;istream& get(istream& in){ int ival; //遇到文件结束符前一直读入数据 while (in >> ival, !in.eof()) { if (in.bad()) //出现系统级故障 throw runtime_error("IO stream corrupted"); if (in.fail()) //出现可恢复错误 { cerr << "bad data, try again" << endl; //提示用户 //有一些编译器不支持in.clear(istream::failbit)语句 所以这里用in.clear() in.clear(); //恢复流 //跳过200个字符或者遇到空格或EOF为止 因此输入时必须以空格为间隔 in.ignore(200, ' '); continue; //继续读入数据 } //读入正常 cout << ival << '\t'; } in.clear(); return in;}//在主函数中测试int main(){ int ival; get(cin); //这里用cin作为我们要读取的流 cin >> ival; //重新使用恢复后的流 cout << ival << endl; return 0;}
输出缓冲区的管理,输出缓冲区中存放着将要输出的数据,当程序结束或缓冲区满或执行一些清空缓冲区的操作时,系统会刷新缓冲区。
c++提供3个操作符用于刷新流,用法如下:
cout << “hi” << flush; //刷新缓冲区,不添加数据
cout << “hi” << ends; //刷新缓冲区,并在输出中插入一个null空字符
cout << “hi” << endl; //刷新缓冲区,并在输出中插入一个换行符
也可以用unitbuf操纵符来实现刷新,使用unitbuf会在每一次输出后刷新缓冲区。
cout << unitbuf << “first” << “second”<< nounitbuf;
这样在输出first后缓冲区被刷新,输出second后,缓冲区再次被刷新,此时缓冲区里啥也没有。但要最后用nounitbuff把流恢复正常。
由于程序崩溃时,系统不会自动刷新缓冲区,那么此时想通过输出来找出错误发生的原因就变得异常艰难,基于这个原因,输出时应当尽可能使用endl而非’\n’。
我们还可以将输入和输出绑在一起,默认标准库是将cout与cin绑在一起,这样在读cin的时候,会导致cout的缓冲区被刷新,我们可以使用tie()来制定需要绑定的流,例如:
cin.tie(&cout); //tie的参数为指向ostream对象的指针
ostream* old_tie = cin.tie(); //返回当前与cin绑定的流指针
cin.tie(0); //解除cin的所有绑定,这样在读cin时,cout缓冲区将不会刷新
cin.tie(&cerr); //将cin与cerr绑定
cin.tie(0); //解除cin与cerr的绑定
cin.tie(old_tie); //恢复cin与cout的绑定
- C++ Primer- 流的条件状态以及缓冲区管理
- C++ Primer 学习笔记_25_标准I/O库 --面向对象的标准库、条件状态、输出缓冲区的管理
- c++primer 第八章IO操控流的条件状态
- 【C/C++】缓冲区输出的条件
- C++:IO流条件状态
- IO流的条件状态
- 【C++ Primer】【学习笔记】【第八章】标准IO库之:输出缓冲区的管理
- Cpp Primer<<学习IO标准库--输出缓冲区的管理、文件输入与输出_6
- 三极管工作状态以及条件
- 输出缓冲区的管理
- 输出缓冲区的管理
- 输出缓冲区的管理
- 内核缓冲区的管理
- 重温《C++ Primer》笔记二 标准IO库的条件状态
- OpenRTMFP/Cumulus Primer(10)IO 管理之流缓冲区
- 进程的三个基本状态,以及三个状态之间切换的条件
- 进程的三个基本状态,以及三个状态之间切换的条件
- 进程的三个基本状态,以及三个状态之间切换的条件
- Cstring转char*
- myeclipse10加入svn插件
- 分组背包dp+并查集 vijos1250
- openwrt 网上资料搜集
- 【剑指offer】字符串的组合
- C++ Primer- 流的条件状态以及缓冲区管理
- Eclipse配置android开发环境
- 进程和线程
- UVa 216 - Getting in Line
- 利用PowerDesigner15在win7系统下对MySQL 进行反向工程(一)
- Android4.2.2下Stagefright多媒体架构中的A31的OMX插件和Codec组件
- C++隐式指针(引用)
- uva 11645 - Bits(计数问题+高精度)
- __getattr__ VS __getattribute__