5.文件操作
程序运行时产生的数据都属于临时数据,程序一旦运行结束会被释放,可以通过文件使数据持久化。C++中对文件操作需要包含头文件<fstream>
(文件流)
文件分为两种类型:
- 文本文件:文本以文本的ASCII码形式存储在计算机中
- 二进制文件:文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们
操作文件的三大类:
项目 | Value |
---|---|
ofstream | 写操作(对程序来说是输出output) |
ifstream | 读操作(对程序来说是输入input) |
fstream | 读写操作 |
5.1文本文件
1.写文件
写文件的步骤如下:
- 包含头文件:
#include<fstream>
; - 创建流对象
ofstream ofs
; - 打开文件
ofs.open{"文件路径",打开方式}
; - 写数据
ofs << "写入的数据"
; - 关闭文件ofs.close();
个人理解:
- 对文件进行写,那么程序就需要输出内容,所以用ofsream表示写操作。o是对程序而言,写是对文件而言。
- 创建了一个流对象,打开文件就相当于该流对象就是文件,然后下一步用左移操作符给流对象输入内容的时候就是给文件输入内容,也就是写操作。所以,在文件操作完毕之后,需要关闭文件,这样输出流对象空闲,为下一个文件操作做好准备。
文件打开方式:
打开方式 | 解释 |
---|---|
ios::in | 为读文件而打开文件 |
ios::out | 为写文件而打开文件 |
ios::ate | 初始位置:文件尾 |
ios::app | 追加方式写文件 |
ios::trunc | 如果文件存在先删除,再创建 |
ios::binary | 二进制方式 |
ios : : out
对文件执行写操作的时候,每次打开文件会把原来的内容清除,或者说是覆盖原来的内容。
文件打开方式可以配合使用,利用 |
操作符。
例如, 用二进制方式写文件 ios::binary | ios::out
程序实例:
#include<iostream>
using namespace std;
#include<fstream>
/******文本文件*****写文件*****/
void test01()
{
// 1.包含头文件 fstream
// 2.创建流对象
ofstream ofs; // 输出流文件 ofs是名字
// 对程序是输出,对文件本身就是写
// 3.指定打开方式
ofs.open("test.txt",ios::out);
// 如果不指定路径,那么默认的路径是当前代码或项目的路径
// 4.写内容---把要写的内容传给输出流对象
ofs << "姓名:张三" << endl; // endl 的换行在文件中同样有用
ofs << "性别:男" << endl;
ofs << "年龄:18" << endl;
// 5.关闭文件
ofs.close();
}
int main()
{
test01();
system("pause");
return 0;
}
2.读文件
读文件步骤:
- 包含头文件
fstream
; - 创建流对象
ifstream ifs
;(文件信息输入到程序) - 打开文件并判断文件是否打开成功
ifs.open("文件路径",打开方式)
; - 读数据 四种方式读取;
- 关闭文件
ifs.close()
#include<iostream>
using namespace std;
#include<fstream>
#include<string>
/******文本文件*****读文件*****/
void test01()
{
// 1.包含头文件
// 2.创建流对象
ifstream ifs;
// 3.打开文件并判断是否成功
ifs.open("test.txt",ios::in);
if( !ifs.is_open() ) //函数返回值是布尔函数,打开成功返回1
{
cout<< "文件打开失败" << endl;
return; // 退出程序,不再继续执行
// 文件名错误或者路径错误等都会打开失败
}
// 4.读文件 四种方式
// Mode 1
char buf[1024] = {0};
while(ifs >> buf) // 读不到数据的时候会返回false,正好退出循环
{
cout << buf << endl;
}
// // Mode 2
// char buf[1024] = {0};
// while(ifs.getline(buf,sizeof(buf)))
// // getline是ifs的成员函数,获取一行的意思
// // 需要两个参数,一个是char*,
// {
// cout << buf << endl;
// }
// // Mode 3
// string buf; // string接收,注意包含头文件
// while( getline(ifs,buf) )
// // 全局函数getline,需要一个流对象,一个存放的位置
// {
// cout << buf << endl;
// }
//
// // Mode 4
// char c;
// while( (c = ifs.get()) != EOF)
// // get是每次只读一个字符
// // 括号中的意思是读到文件尾
// // EOF end of file
// {
// cout << c;
// }
// 不推荐,因为一个一个读比较慢
// 5.关闭文件
ifs.close();
}
int main()
{
test01();
system("pause");
return 0;
}
5.2二进制文件
以二进制方式对文件进行读写操作。打开方式要指定为 ios::binary
二进制的文件打开txt文档自己看的时候可能会出现乱码等问题,但是只要能够正确读入就好,可能本身就是为了不让人看懂。
1.写文件
写文件主要利用流对象调用成员函数 write
函数原型:
ostream write(const char * buffer, int len);
字符串指针buffer
指向内存中的一段空间,len
是读写的字节数
#include<iostream>
using namespace std;
#include<fstream>
/******二进制文件*****写文件*****/
// 可以操作内置数据类型和自定义数据类型
class Person
{
public:
char m_Name[64]; // 底层是C实现的,用string会出现问题
int m_Age;
};
void test01()
{
//1.包含头文件
//2.创建流对象
ofstream ofs;
// ofstream ofs("Person.txt",ios::out | ios::binary)
// ofs中的构造函数可以使得在指定对象的同时也创建好所有打开方式
//3.打开文件
ofs.open("Person.txt",ios::binary|ios::out);
//4.写文件
Person p = {"张三",18};
ofs.write((const char *)&p,sizeof(Person)); // 强制类型转换
//5.关闭
ofs.close();
}
int main()
{
test01();
system("pause");
return 0;
}
2.读文件
读文件主要利用流对象调用成员函数 read
函数原型:
istream& read(char * buffer, int len);
字符串指针buffer指向内存中的一段空间,len是读写的字节数。
#include<iostream>
using namespace std;
#include<fstream>
/******二进制文件*****读文件*****/
class Person
{
public:
char m_Name[64];
int m_Age;
};
void test01()
{
//1.包含头文件
//2.创建流对象
ifstream ifs;
//3.打开文件并判断是否成功
ifs.open("Person.txt",ios::in|ios::binary);
if(!ifs.is_open())
{
cout << "文件打开失败" << endl;
return;
}
//4.读文件
Person p;
ifs.read( (char*)&p, sizeof(Person)); // 强制类型转换
cout << "Name: " << p.m_Name << " " << "Age: " << p.m_Age << endl;
//5.关闭
ifs.close();
}
int main()
{
test01();
system("pause");
return 0;
}