一、前言:
在C++里,文件操作是通过流来完成的。C++总共有输入文件流、输出文件流和输入输出文件流3种,并已将它们标准化。C++中对文件操作需要包含头文件 < fstream >
C++中文件类型分为两种:
文本文件 - 文件以文本的ASCII码形式存储在计算机中
二进制文件 - 文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们
操作文件的三大类(这些类都属于标准模板库):
ofstream(output):写入文件操作
ifstream(input): 读取数据操作
fstream : 读写操作。一般使用这个类进行文本操作
这3种类型都定义在头文件 fstream 里,这 3 个文件流类的继承关系,如图 1所示。
二、C++文件操作
文件操作简单来说就是分三步:打开文件、进行读/写操作、关闭文件,而这些操作大多是通过一系列函数实现的
打开文件前我们首先创建流对象,然后用流对象引用其他函数。
第一步:打开文件:
1.文件打开函数open()
void open(const char* szFileName, int mode)
- 第一个参数是文件名
文件名可以是全路径的,如c:\\tmp\\test.txt, 指明文件在 c 盘的 tmp 文件夹中;也可以只给出文件名,如第test1.txt,这种情况下程序会在你程序所在文件夹中寻找要打开的文件。 - 需要注意的是,在 Windows 操作系统中,文件路径中的反斜杠(\)需要使用两个来进行转义(\)
-第二个参数是文件打开方式
打开的方式还可也用 “|” (或)来组合,例如:
open函数其实还有第三个参数,但是在大多情况下我们并不用写,第三个参数是个数值,不写默认是读/写普通文件打开
第二步:文件读写
思路说明:
文件读/写分为文本文件和二进制文件的读/写,读写也分为顺序读写和随机读写。
1.写文本文件(输出操作)
将程序内部数据的值存储到磁盘文件中。因此写入文本文件被称为输出操作。
步骤:
1.包含头文件
#include
2.创建流对象
ofstream ofs;
3.打开文件
ofs.open(“文件路径”,打开方式);
4.写数据
ofs << “写入的数据”;
类似于cout<<“…”; cout就是往屏幕上输出,而ofs就是往文件里输出
5.关闭文件
ofs.close();
#include<fstream>
#include<iostream>
using namespace std;
int main()
{
ofstream ofs;// 2.创建流对象
ofs.open("test.txt", ios::out);
ofs << "姓名:张三" << endl << "年龄:19" << endl << "性别:男" << endl;
ofs.close()``;
return 0;
}
2.读文本文件(输入操作)
将磁盘文件中存储的数据值加载到程序内部内存中,读取文本文件被称为输入操作。
读文件与写文件步骤相似,但是读取方式相对于比较多,在者就是要判断打开文件是否成功(就是判断一下有没有这个文件)。
- 判断文件是否打开成功(其实也就是判断有没有这个文件):
if (!ifs.is_open())
{
cout << "文件打开失败" << endl;
return;
}
if_open()是系统自带的布尔类型函数,打开成功返回1
打开失败返回0(这个函数是判断文件是否存在的)
类似的还有其他函数:
- 读取文件
1.第一种方式:把文件内容全部放在字符数组中
//第一种方式
char buf[1024] = { 0 };//首先初始化字符数组
while (ifs >> buf)
// ifs右移运算符,他会读取数据并放到buf数组中,
//当数据全部读完后,返回一个false,while循环也就结束了
{
cout << buf << endl;
}
2.第二种方式:使用字符数组作为缓存,输出文件内容。使用getline函数读出数据。
ifs.getline(char *str,count)//从文件中读取一行字符串,配合while可读取全部数据
char *str:表示我们要把读取的数据放到哪个地方,一般是个数组
count:所占的空间
//第二种
char buf[1024] = { 0 };
while (ifs.getline(buf,sizeof(buf)))
{
cout << buf << endl;
}
3.第三种方式:把内容放到string字符串中
然后使用函数getline(输入流对象,准备好的字符串)
//第三种
string buf;
while (getline(ifs, buf))
{
cout << buf << endl;
}
4.第四种方式:get()函数
ifs.get()每次只读一个字符。EOF代表末尾的意思
// 第四种
char c;
while ((c = ifs.get()) != EOF)
{
cout << c;
}
3.写二进制文件(输入操作)
1.用write()函数
函数原型 :ostream& write(const char * buffer,int len);
参数1:字符指针常量buffer(也可以理解为就是一段地址(指针就是地址),不过要把它强制转换成const char * ) 。 buffer指向内存中一段存储空间。简单来说就是buffer 用于指定要写入文件的二进制数据的起始位置。
数组名就可以直接作为参数一,当传数组给一个函数时,数组类型自动转换为指针类型,传的实际是数组元素首地址。
参数二:len用于指定写入字节的个数。
注意:参数一不能是string类地址
下面的程序演示了如何将学生信息以二进制形式写入文件:
#include <iostream>
#include <fstream>
using namespace std;
class CStudent
{
public:
char szName[20];
int age;
};
int main()
{
CStudent s;
ofstream outFile("students.dat", ios::out | ios::binary);
while (cin >> s.szName >> s.age)
outFile.write((char*)&s, sizeof(s));
outFile.close();
return 0;
}
4.读二进制文件(输出操作)
1.使用read()函数
istream & read(char* buffer, int count);
和write函数一样,buffer 用于指定读取字节的起始位置,count 指定读取字节的个数。同样,该方法也会返回一个调用该方法的对象的引用。
我们将 3 个学生的信息存储到了 students.dat 文件中,下面程序演示了如何使用 read() 方法将它们读取出来:
#include <iostream>
#include <fstream>
using namespace std;
class CStudent
{
public:
char szName[20];
int age;
};
int main()
{
CStudent s;
ifstream inFile("students.dat",ios::in|ios::binary); //二进制读方式打开
if(!inFile) {
cout << "error" <<endl;
return 0;
}
while(inFile.read((char *)&s, sizeof(s))) { //一直读到文件结束
cout << s.szName << " " << s.age << endl;
}
inFile.close();
return 0;
}
5.文件指针(文件的随机读写)
上面的读写方式其实就是顺序读写,打开文件默认指针就在最开始的位置,所谓的随机读写其实就是从你想要的位置开始读/写,通过函数实现。
1.seekg()函数,可以设置文件读指针的位置;
istream & seekg (int offset, int mode);
举个栗子:
file.seekg(0,ios::beg); //让文件指针定位到文件开头
file.seekg(0,ios::end); //让文件指针定位到文件末尾
file.seekg(10,ios::cur); //让文件指针从当前位置向文件末方向移动10个字节
file.seekg(-10,ios::cur); //让文件指针从当前位置向文件开始方向移动10个字节
file.seekg(10,ios::beg); //让文件指针定位到离文件开头10个字节的位置
常用的错误判断方法:
good() 如果文件打开成功
bad() 打开文件时发生错误
eof() 到达文件尾
2.seekp() 成员函数,可以设置文件写指针的位置。
参数用法和seekg函数一样,不再解释。
3.tellg()和tellp()
- ellg 成员函数,能够返回文件读指针的位置;
- tellp 成员函数,能够返回文件写指针的位置。
用法:
int a=流对象.tellg();//返回值为int类型
第三步:关闭文件
1.close()函数
流对象.close();
文件最后一定要用close()函数关闭.
三、总结:
- 写文件步骤:
1、包含头文件#include<fstream>;
2、创建流对象 ofstream ofs
3、打开文件 ofs.open(“文件路径”,打开方式)
4、写数据 ofs<<“写入的数据”
5、关闭文件 ofs.close() - 读文件步骤:
1、包含头文件#include<fstream>;
2、创建流对象 ifstream ifs;
3、打开文件并判断文件打开是否成功 ifs.open(“文件路径”,打开方式);
4、读数据 四种方式读取;
5、关闭文件 ifs.close();
关于具体的实例可以看以下文章:
例题1:从键盘读入一行字符,把其中的字母依次放在磁盘文件fa2.dat中,再把它从磁盘文件读入程序,将其中的小写字母改成大写字母,再存入磁盘fa3.dat中
点此跳转
例题2:C++读/写文件:点此跳转(1) 点此跳转(2)
说明:
文件读写那只是截取了部分代码,说明读写方式,如果想要看完整的代码:点此跳转
若想要更为深入的了解其中的原理可以看这篇文章:小熊coder【C++学习笔记】C++文件操作