C++文件输入输出流fstream的基本用法

马谦马谦马谦 C/C++评论3,5672字数 2034阅读6分46秒阅读模式

一、文件流

C++的IO类中定义了三个文件读写流fstream、ifstream以及ofstream,它们都继承于相同的父类istream,通过不同的实现以实现不同的文件流操作。

三者的区别为:

  • ifstream:从文件读取数据
  • ofstream:从文件写入数据
  • fstream:既可以读数据、又可以写数据

1.1 IO接口和读写模式

三个文件流实现了以下几个函数接口:

函数名 用途
open(s, mode) 以mode模式打开文件s
close() 关闭文件流
is_open() 返回文件是否已经打开
read(buff, size) 读入最多size字节数据到buff中
write(buff, size) 写入size字节数据到文件中

在使用open的时候,可以只传入文件s,不指定打开模式。如果不指定模式,系统会自动根据文件类型选择默认的打开模式。同时,除了open()的方式打开文件以外,还可以在对象构造的时候打开文件:

ios::out表示已只读方式打开文件,对应unix c中的O_WRONLY模式。在C++中,有以下读写模式可以选择:

模式 说明
ios::in 以读方式打开
ios::out 以写方式打开
ios::app 以追加写方式打开
ios::trunc 以截断方式打开文件
ios:binary 以二进制方式打开文件
ios::ate 打开文件后指针定位到文件尾

这些模式可以单独使用,也可以组合使用,如果需要组合使用,使用逻辑操作符|或起来即可。这里要特别注意的是ios::out模式默认会截断文件,也就是说,ios::outios::out | ios::trunc效果是一样的,都会将文件截断。如果不希望以截断方式打开文件时,则需要设置读写模式为ios::out | ios::app,以这种模式打开文件后,数据会以追加的方式写入到文件。

1.2 读写文件示例

写文件

读文件

打印结果:

C++文件输入输出流fstream的基本用法-图片1

1.3 以IO操作符读写数据

三个IO操作类都继承于istream,可以直接使用IO操作符(<<>>)来进行文件读写。

注意:在使用IO操作符从文件读取数据的时候,数据输入的对象可以是字符串,也可以是对应的数据类型(如int)。如果输入到字符串,默认是读到空白字符的时候就停止了,需要通过循环控制读取后面的数据。

二、流状态

流在执行IO操作的时候,会根据不同的情况产生不同的状态码,如:

状态位 说明
strm::badbit 流已崩溃
strm::failgit IO已崩溃
strm::eofbit 已经读到文件尾
strm::goodbit 一切正常,没有异常

我们可以使用已经封装好的函数bad()/fail()/eof()/good()来判断当前IO是否已经达到某种状态,如判断文件是否已经读到结束。同时,我们还可以使用clear()函数来清除当前IO对象的状态位,当流已崩溃(如将流中的字符串对象读到一个int对象上)时,可以手动来清除状态位继续往下读取。

示例,使用eof标志位判断文件是否读完成

因为使用IO操作符从流中读取数据默认遇到空行就停止,所以Hello World\n字符串需要读三次才能读完,第一次是Hello,第二次是World,第三次是换行后的空行,所以,最后的输出结果是:

C++文件输入输出流fstream的基本用法-图片2

三、getline一次读一行

流对象中内置了getline()成员方法可以一次读一行数据到字符串数组中,需要传入一个字符数组和最大长度size:

这个成员方法可以实现一次读一行的操作,但是只支持C风格的字符串传入,无法支持C++中的string类型。这里可以使用系统库的getline()函数来实现,系统库中有一个getline()函数可以直接从IO流中读取一行数据到string中:

上面两个实现都可以正常按行输出文件内容:

C++文件输入输出流fstream的基本用法-图片3

四、fstream和文件指针

当使用fstream流时,对象既可以写入文件,也可以读取文件。此时读写文件指针是公共的,写入文件会导致指针后移,再读就会从当前位置重新读取(读到垃圾数据)。为了避免这个问题,可以使用seekp和seekg来移动文件指针:

五、错误处理

5.1 读取文件失败了,应该如何判断

执行完open操作后,直接判断对象是否为真即可确定打开文件是否失败。出现错误后,可以使用errno输出错误原因。

例如,打开一个不存在的文件:

输出结果会打印出文件不存在的错误:

C++文件输入输出流fstream的基本用法-图片4

 最后更新:2021-4-6
马谦马谦马谦
  • 本文由 马谦马谦马谦 发表于 2020年12月26日22:11:34
  • 转载请务必保留本文链接:https://www.dyxmq.cn/program/code/c-cpp/fstream.html
C++11中const_cast的真实使用场景 C/C++

C++11中const_cast的真实使用场景

一、const和成员函数的故事 const的用途有以下几种: 修饰全局、局部、成员变量 修饰成员函数 修饰变量的时候const限制了变量在整个程序运行期间都是不能修改的,而修饰成员函数的时候限制函数内...
C++11中的override和final关键字 C/C++

C++11中的override和final关键字

一、前言 昨天在公司做代码扫描,发现很多类似以下的代码都产生了告警,导致扫描不通过: virtual int func() override {} 不通过的原因是:同时使用virtual和overri...
匿名

发表评论

匿名网友
:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:
确定

拖动滑块以完成验证