文件流类
文件流类是用于操作文件的标准C++类
ifstream
: 从文件读取数据ostream
: 向文件插入数据fstream
: 可读取插入
文件分类
文件分为文本文件以及二进制文件:
- 文本文件:是一种由若干行字符构成的计算机文件。其编码可以是ASCII码、UNICODE码、GBK编码等等。可以用文本编辑器编辑
- 二进制文件:除了上述以字符构成的文本文件,其他文件均称为二进制文件。典型的二进制文件有声音、动画、图像、视频等
c++语言对上述两种文件都可以进行创建、读写等操作。
文件操作的基本步骤
- 1.定义一个文件流对象
- 2.打开文件
- 3.读 / 写文件
- 4.关闭文件
ifstream 对象只进行读操作
ofstream 对象只进行写操作
fstream 对象既可以读文件,也可以写文件
文件的打开
文件流类的成员函数open(打开文件)形式如下:
void open (const char * filename, openmode mode)
其中,filename 是文件名(如 e:\c++\file.txt)(路径+文件名),若缺少路径,则默认为当前目录。
mode 指文件打开方式,内容如下:
ios::ate
与ios::app
区别是ios::ate
会覆盖之前的内容
每打开一个文件都有一个文件指针,指针的开始位置由打开方式指定,每次读写都从文件指针的当前位置开始。
还可以用文件流类的构造函数来打开文件,其参数和默认值与open函数完全相同。
例子:
- 1.在工程默认目录打开文件grade.txt,只用于输入
ifstream file1;
file1.open("grade.txt", ios::in);
- 2.打开文本文件c:\msg.txt,只用于输出
ofstream file2;
file2.open("c:\\msg.txt"); //第二个参数省略, windows中要用双斜杠
- 3.以二进制输入方式打开文件c:\abc.bmp
fstream file3;
file3.open("c:\\abc.bmp",ios::binary|ios::in);
- 4.用构造函数来打开二进制文件,用于输出
ofstream file ("example.bin", ios::out|ios::binary);
文件的关闭
- 关闭文件操作包括把缓冲区数据完整地写入文件,添加文件结束标志,切断流对象和外部文件的连接
- 当一个流对象的生存期结束,系统也会自动关闭文件
- 若流对象的生存期没有结束,用
close()
关闭文件后,该流对象可以重用
文本文件的读写
以ifstream
、ofstream
为例说明。
由于ifstream
、ofstream
类继承自流类istream
和ostream
,因此也可以使用常见的IO操作。
比如>>、get、getline
常用于文本文件输入
,而操作<<、put
常用于输出
。
例子:
用符号<<
和 put
函数向文本文件写入一些文字
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
//打开文件
ofstream out("file.txt");
if(!out)
{
cout<<"打开文件失败!"<<endl;
return 1;
}
//写文件
out<<"Welcome to ";
char ch[] = "BeiJing.";
int i=0;
while(ch[i]!=0)
{
out.put(ch[i]); i++;
}
out.close(); //关闭文件
return 0;
}
运行结束后,在工程目录下产生文件file.txt
,内容如下:
Welcome to BeiJing.
用符号 >>
和 get 函数
读取文本文件
本例将上一个例子建立的文件内容读出并显示在屏幕上
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
//打开文件
ifstream in("file.txt");
if(!in)
{
cout<<"不可以打开文件"<<endl;
return 1;
}
//读文件
char ch[80];
in>>ch; //读取第一个单词Welcome
cout<<ch;
in>>ch; //读取第二个单词to
cout<<ch;
while(in) //剩余部分用get函数读出并显示
{
char c=in.get();
if(in)
cout<<c;
}
in.close(); //关闭文件
return 0;
运行后,屏幕显示:
Welcome to BeiJing.
如何判断读到达文件尾部
当没有读到文件尾部时,ifstream
对象 in
相当于一个true值,甚至直到读取完所有有效数据后,in
仍然相当于true
。这时再读取一次文件后,in
才变成了相当于false
值的对象。
while(in)
{
char c=in.get();
if(in)
cout<<c;
}
之所以要有 if
判断,是为了不输出最后一次读取的非正文数据
综合实例
统计平均成绩
假设一个文件file.txt
,内容为学生成绩,每一行的形式为:姓名、数学成绩、英语成绩、物理成绩
。数据中间用空格隔开。编写程序读取每一行的内容,计算出每人的平均成绩后,写入输出文件。输出文件名由用户输入,输出文件每一行的形式为:姓名、数学成绩、英语成绩、物理成绩、平均成绩
。
// file.txt
张三 87 66 89
李四 98 79 77
王五 89 92 89
实现代码如下
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char ch[20]; // 用于保存姓名
int math, eng, phy;
// 打开文件
ifstream fin("file.txt");
ofstream fout("res.txt");
if (!fin || !fout )
{
cout << "不可以打开文件" << endl;
return 1;
}
// 读文件并写到文件res.txt
while(fin)
{
fin >> ch >> math >> eng >> phy;
if(fin)
{
float avg = 1.0 * (math+eng+phy)/3;
fout << ch << "\t" << math << "\t" << eng << "\t" << phy << "\t" << avg << endl;
}
}
// 关闭文件
fin.close();
fout.close();
return 0;
}
输出结果
// res.txt
张三 87 66 89 80.6667
李四 98 79 77 84.6667
王五 89 92 89 90