IO库-C++Primer学习笔记

本文深入探讨C++中的IO流状态,包括iostate类型、条件状态的管理及流对象成员函数的使用。同时,详细解析输出缓冲区的管理、刷新操作以及如何关联输入和输出流。此外,还介绍了文件输入输出的基本操作和文件模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IO类的条件状态

IO库定义了:

  • iostate类型,提供表达流状态的完整功能
  • 4个 iostate类型的constexpr 值,用来表达特定的位模式。
常量含义failbit标记位的值eofbit标记位的值badbit标记位的值转化为10进制
failbit输入(输出)流出现非致命错误,可挽回1004
eofbit已到达文件尾0102
badbit输入(输出)出现致命错误,不可挽回0011
goodgit流状态完全正常0000

转化为10进制

如果到达文件的末尾,eofbit和failbit都会被置位。
bad、fail、eof任意一个被置位,检测流状态的条件会失败。

  • iostate 类型constexpr值的返回值:
    good 在所有错误均为置位返回 true
    bad、eof、fail 则在对应错误被置位时返回true
    bad被置位时,fail也会返回true;

所以使用fail、good用于确定流状态的正确方法,eof和bad只用于表示特定错误。

  • 管理条件状态

流对象中定义了一些成员函数。

  • rdstate(),返回一个iostate值,对应流的当前状态。
  • setstate():将给定条件位置位,表示发生了相应的错误。
  • clear():是一个重载函数,有不接受参数和接收参数两个版本。
    不接受参数的版本:清除(复位)所有的错误标志位,执行clear()后,good返回true
    含参数的clear接受一个iostate值,表示流的状态。表示新的流状态。
int main() {
 //cin>>1;输出 0;
 //cin>>q;输出 2;
 int a; cin >> a;
 auto old_state = cin.rdstate();
 cout << old_state;
 return 0;
}

管理输出缓冲区

每个输出流都管理者一个缓冲区,用来保存程序读写的数据。

  • 什么是缓冲区?
    cout通过ostream连接到输出设备上(显示器等)。
    当有数据要输出的时,cout先通过ostream将数据写入缓冲区,当缓冲区写满或流关闭的时候,数据将被发送到输出设备上(被显示)。而刷新缓冲区,不管缓冲区有没有被写满,数据直接被发往输出设备。

通过缓冲机制,操作系统可以将程序的多个输出操作组合成单一的系统级写操作。由于设备的写操作可能很耗时,允许操作系统将多个输出程序组合为单一的设备写操作可以带来很大的性能提升。

  • 导致缓冲刷新(数据真正写道输出设备或文件)的原因有很多。
  • 程序正常结束,作为main函数的renturn操作的一部分,缓冲刷新被执行。
  • 缓冲区满时,需要刷新缓冲,而后新的数据才能继续写入缓冲区
  • 可以使用操纵符如endl来显示地刷新缓冲区
  • 在每个输出操作之后,可以用unitbuf设置流的内部状态,来清空缓冲区。默认情况下,对
    cerr是设置unitbuf的,因此写到cerr的内容都是立即刷新的
  • 一个输出流可能被关联到另一个流。在这种情况下,当读写被关联的流时,关联到的流的缓冲区会被刷新。例如,默认情况下,cin和cerr都关联到cout。因此,读cin或写cerr都会导致cout的缓冲区被刷新
    ————————————————————————————————————————————
    摘自C++primer 5th p281
  • 刷新输出缓冲区
    可以使用操作符endl、ends、flush
符号功能
endl输出换行,然后刷新缓冲区
flush刷新缓冲区,不附加任何字符
ends输出一个空字符,然后刷新缓冲区

如果想在每次输出操作之后都刷新缓冲区,我们可以使用unitbuf操纵符,它表示接下来每次写操作之后都执行一次flush(写操作就是写到输出设备中)。

  • 关联输入和输出流
    当一个输入流被关联到一个输出流的时候,任何试图从输入流读取数据的操作都会先刷新关联的输出流,**标准库将cout与cin关联在一起。
    语句cin>>ival语句会先刷新cout的缓冲区,再进行cin的输入。

文件输入输出

语句作用
fstreaam fstrm;创建一个未绑定的文件流,fstream是一个类型
fstream fstrm(s);创建一个fstream,并打开名为s的文件。s可以是string字符串也可以是指向C风格字符串的指针。构造函数为explicit,mode依赖于fstream类型
fstream fstrm(s,mode)’与上面相似,按照mode打开文件
fstrm.open(s)打开名为s的文件,并于fstrm绑定。返回void
fstrm.close()关闭与fstrm绑定的文件
fstrm.is_open()返回一个bool值,指出与fstrm关联的文件是否成功打开且尚未关闭
  • getline()函数的使用

getline(cin,StringName);
cin是输入流,之后的StringName是接收输入流的容器。

在输入文件的时候,要记得使用if语句检查文件是否成功读取的好习惯。

string infile;
fstream in(infile);
if(in){...;}//养成检查文件是否读入的好习惯!!
else 
cout<<"something wrong happened"<<endl;
  • 文件模式
名称含义
in以读方式打开
out以写方式打开
app每次写操作前军定义到文件末尾
ate代开文件后立刻定位到文件末尾
trunc截断文件
binary以二进制进行IO

以out代开文件会丢弃已有数据
默认情况下打开ofstream时文件会被清空(覆盖然后填充新内容)。阻止其清空的方式是同时指定app模式。

ofstream app("file.1",ofstream::app);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值