c++primer 第八章 IO库

8.1 IO类

  • iostream读写流,fstream读写文件,sstream读写内存string对象
    在这里插入图片描述

  • 宽字符(wchar_t)支持:宽字符版本的类型和函数以w开始,例如wcin,wcout,werr,头文件在wiostream中

  • 继承关系:如ifstream,istringfstream都继承于istream

8.1.1 IO对象无拷贝或复制

  • 不能拷贝或对IO对象赋值
  • 因此不能把形参或者返回类型设置为流类型; 通常通过引用方式传递和返回流。
  • 因为读写流会改变流对象的状态,因此传递和返回的流也不能是const

8.1.2 条件状态

在这里插入图片描述在这里插入图片描述

  • 一个流一旦发生错误,其后续IO操作都会失败
  • 确定流状态的最好的方法:
while(cin >> word){
	//流状态正常会执行
	}
  • 查询流的状态
    IO库中定义了和机器无关的iostate类型,可以使用iostate类型的badbit、failbit、eofbit、goodbit来判断流的状态。
    • badbit:系统级错误,如不可恢复的读写错误 ;badbit置位后,流不可用;
    • failbit:可恢复的错误,如期望得到数值但得到字符;failbit置位后,修正流的状态,流可以继续使用
    • eofbit:文件结束后,eofbit和failbit同时置位。
    • goodbit:流无错误
    • 若badbit、failbit、eofbit有一个置位,检测流的状态都会返回false
  • 管理条件状态
    流有以下成员函数来管理流的状态
    • rdstate():返回一个iostate类型值,对应流现在状态
    • setstate():将给定条件置位
    • clear():不接受参数版本,清除所有错误标志位,执行clear()后,流可用;带参数版本,效果和setstate相同。
auto old_state = cin.rdstate();//保存旧状态
cin.clear();//使cin有效
process_input(cin);//使用cin
cin.setstate(old_state );//将cin恢复到原来状态

//复位failbit和badbit,其他位不变
cin.clear(cin.rdstate() &~cin.failbit &~cin.badbit);

8.1.3 管理输出缓冲

  • 缓冲刷新后,数据从缓冲区打印出或写到磁盘,不保存在内存中;导致缓冲刷新的原因有:
    • 程序结束,main函数return
    • 缓冲区满
    • 调用endl等操作符
    • 使用操作符unitbuf设置流的内部状态;默认情况下,cerr设置了unitbuf,写道cerr中的内容立即执行
    • 一个流可以关联另外一个流;读写被关联流时,关联到的流的缓冲区会被刷新
  • unitbuf操作符
    • 设置unitbuf后,每次读写操作后都进行一次flush
    • 设置nounitbuf后,使用正常系统管理的缓冲区刷新机制
    • 警告:程序崩溃,输出缓冲区不会被刷新;这时输出数据被挂起,想不到这茬,容易debug没思路
  • 关联输入和输出流
    • note:交互式系统通常应该关联输入流和输出流;这意味着所有输出,包括用户的提示信息,都会在读操作之前打印出来
    • 使用tie可以关联输入输出流
    • 不带参数版本:关联到输出流,返回该输出流指针;未关联到流,返回空指针
    • 带ostream指针参数,将自己关联到该ostream
cin.tie(&cout);   //将cin和cout关联在一起
ostream *old_tie =cin.tie(nullptr);		//cin不关联任何流,并返回原来关联的流的指针
cin.tie(&cerr);		//读取cin会刷新cerr
cin.tie(&old_tie)	//重建cin和原关联流的联系

8.2 文件输入输出

在这里插入图片描述

8.2.1 使用文件流对象

  • 创建文件流对象,若提供文件名,open自动调用
  • 成员函数open和close
    • 空的文件流对象可以使用open函数和文件关联起来
    • 对一个已经和文件关联的流调用open,failbit会置位;若想关联到其他文件,要先调用close。
    • 调用open失败,failbit会被置位;调用open后检查是否调用成功
fstream out;
out.open("a.txt");
if(out){
	//文件操作
}
  • 自动构造和析构
    fstream被销毁时,会自动调用close函数

8.2.2 文件模式

在这里插入图片描述

  • 文件模式限制
    • out:对ofstream和fstream使用
    • in:对ifstream和fstream使用
    • trunc:只有设置为out模式后,才能设置为trunc
    • app:没设置trunc才可以设置app模式;app模式下,默认是out模式
    • 默认情况下out模式打开的文件,即使没指定trunc,文件也是截断的;要保留用out模式打开的文件,应该设app模式,数据被追加到文件尾;同时设置in模式,就可以同时对文件进行读写操作
    • ate和binary可以对任何类型摁键流对象使用,和任意模式组合
  • 以out模式打开 文件会丢弃已有数据;阻止该行为的方法是设置app或者in模式
//文件被截断
ofstream out("file");//隐含截断
ofstream outs("file",ofstream::out);//隐含截断
ofstream outs("file",ofstream::out|ofstream::trunc);//显式截断
//文件被保留
ofstream outs("file",ofstream::app);
ofstream //显式保留outs("file",ofstream::out|ofstream::app);//显式保留
  • 每次调用open时,都会确定文件模式

8.3 string流

在这里插入图片描述

8.3.1 使用istringstream

  • 对整行文件进行处理,其他工作处理单词时,使用istringstream很方便
    例子:文件原格式为姓名+若干电话:
乔纳森 138XXXXXXXXXX 138XXXXXXXXXX
乔瑟夫 138XXXXXXXXXX
空条承太郎 138XXXXXXXXXX
东方仗助 138XXXXXXXXXX 138XXXXXXXXXX
空条徐伦 138XXXXXXXXXX 138XXXXXXXXXX 138XXXXXXXXXX
strcut JOJO{
	string name;
	vector<string> phones;
};
string line,phone;
vector<JOJO> jojos;

while(getline(cin,line)){
	JOJO jojo;
	//note:如果是在while外声明istringstream 很容易错,见练习8.11
	//istringstream 声明在while外,这里使用record.str(line)
	//但是record的failbit和badbit是置位的,需要record.clear()
	istringstream record(line);
	record >>jojo.name;
	while(record>>phone){
		jojo.phones.push_back(phone);
	}
	jojos.push_back(jojo);
}

8.3.2 使用ostingstream

  • 在逐步构造希望最后一起打印时,ostingstream很有用。
    使用过程中可以把ostingstream当成一个没有大小显示的缓存区使用,最后要获取ostingstream中内容,使用ostingstream::str()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值