C++中的文件操作



文件操作


视频链接



C++中的文件操作时基于面向对象的


程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放

通过文件可以将数据持久化

C++中对文件操作需要包含头文件 < fstream >



C++中文件类型分为两种:

  1. 文本文件 - 文件以文本的ASCII码形式存储在计算机中
  2. 二进制文件 - 文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们


操作文件的三大类(这些类都属于标准模板库):

  1. ofstream(output):写入文件操作
  2. ifstream(input): 读取数据操作
  3. fstream : 读写操作。一般使用这个类进行文本操作



1 文本文件

1.1 写文件

写文件步骤如下:
  1. 包含头文件

    #include <fstream>

  2. 创建流对象

    ofstream ofs;

  3. 打开文件

    ofs.open(“文件路径”,打开方式);
    文件路径可以直接写个文件名,因为如果不指定路径的话,他会默认在当前项目路径下。

  4. 写数据

    ofs << “写入的数据”;
    类似于cout<<“…”; cout就是往屏幕上输出,而ofs就是往文件里输出

  5. 关闭文件,这一步很重要而且容易遗漏

    ofs.close();



文件打开方式:

在这里插入图片描述



#include<iostream>
using namespace std;
#include<string>
// 1.包含头文件 fstream
#include<fstream>
// 文本文件 写文件
void test01() {
	// 1.包含头文件
	// 2.创建流对象
	ofstream ofs;
	// 3.指定打开的方式
	//文件名为test.txt
	ofs.open("test.txt", ios::out);
	// 4.写内容
	ofs << "姓名:张三" << endl << "年龄:19" << endl << "性别:男" << endl;
	// 5.关闭文件
	ofs.close();

}
int main() {
	test01();
	cin.get();
	return 0;


}

在这里插入图片描述



在这里插入图片描述

总结:

  • 文件操作必须包含头文件 fstream
  • 读文件可以利用 ofstream ,或者fstream类
  • 打开文件时候需要指定操作文件的路径,以及打开方式
  • 利用<<可以向文件中写数据
  • 操作完毕,要关闭文件




1.2 读文件

读文件与写文件步骤相似,但是读取方式相对于比较多

读文件步骤如下:

  1. 包含头文件

    #include <fstream>

  2. 创建流对象

    ifstream ifs;

  3. 打开文件并判断文件是否打开成功

    ifs.open(“文件路径”,打开方式);

  4. 读数据

    四种方式读取

  5. 关闭文件,记住别忘了要关闭文件

    ifs.close();



判断文件是否打开成功(其实也就是判断有没有这个文件):

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;
	}


  1. 第二种方式:使用ifs.getline()函数
    ifs.getline(char *str,count)中有两个参数;

char *str:表示我们要把读取的数据放到哪个地方,一般是个数组
count:所占的空间
在这里插入图片描述



//第二种
	char buf[1024] = { 0 };
	while (ifs.getline(buf,sizeof(buf)))
	{
		cout << buf << endl;
	}


  1. 第三种方式:把内容放到string字符串中
    包含头文件include
    然后使用函数getline(输入流对象,准备好的字符串)
//第三种
	string buf;
	while (getline(ifs, buf))
	{
        cout << buf << endl;
	}


  1. 不太推荐的第四种方式:他会将文件中的所有数据一个一个地读出来,放到字符C里边。效率太差

ifs.get()每次只读一个字符。EOF代表末尾的意思

// 第四种
	char c;
	while ((c = ifs.get()) != EOF)
	{
		cout << c;
	}



综合
#include<iostream>
using namespace std;
//1. 包含头文件
#include<fstream>
#include<string>



void test01()
{   // 2. 创建流对象  
	ifstream ifs;


	//3. 打开文件并判断文件是否打开成功
	ifs.open("test.txt", ios::in);


	if (!ifs.is_open())
	{
		cout << "文件打开失败" << endl;
		return;
	}

	// 4. 读数据
	// 四种方式

	//第一种方式
	//char buf[1024] = { 0 };
	//while (ifs >> buf)
	//{
	//	cout << buf << endl;
	//}
	






	//第二种
	//char buf[1024] = { 0 };
	//while (ifs.getline(buf,sizeof(buf)))
	//{
	//	cout << buf << endl;
	//}

	//第三种
	string buf;
	while (getline(ifs, buf))
	{
        cout << buf << endl;
	}


	// 第四种
	//char c;
	//while ((c = ifs.get()) != EOF)
	//{
		//cout << c;
	//}


	// 5. 关闭文件
	ifs.close();


}

int main() {

	test01();

	system("pause");

	return 0;
}

在这里插入图片描述






2 二进制文件(不仅可以操作内置数据类型还可以操作自定义数据类型)

以二进制的方式对文件进行读写操作

注意打开方式要指定为 ios::binary



2.1 写文件

二进制方式写文件主要利用流对象调用成员函数write

函数原型 :ostream& write(const char * buffer,int len);

在这里插入图片描述





参数解释:参数一:字符指针常量buffer(也可以理解为就是一段地址(指针就是地址),不过要把它强制转换成const char * ) 。 buffer指向内存中一段存储空间。len是读写的字节数

数组名就可以直接作为参数一,当传数组给一个函数时,数组类型自动转换为指针类型,传的实际是数组元素首地址。

建议看的文章1:将地址强制转换为指针

建议看的文章2指针的强制类型转换



注意:对文件操作时,字符串最好使用C语言风格的字符串(也就是字符数组)因为wirte()和read函数()都包含参数char *,用string会引发错误

在这里插入图片描述



#include<iostream>
using namespace std;

#include <fstream>
#include <string>

class Person
{
public:
	char m_Name[64];
	int m_Age;
};

//二进制文件  写文件
void test01()
{
	//1、包含头文件

	

	//2、创建输出流对象
	ofstream ofs("person.txt", ios::out | ios::binary|ios::trunc);

	//3、打开文件
	//ofs.open("person.txt", ios::out | ios::binary);

	int a = 55;
	int d[20];
	for (int i = 0; i < 20; i++) {

		d[i] = i;
	 }
	Person p = { "张三"  , 18 };

	char c[15] = { "Hello,World!" };

	//4、写文件
	ofs.write((const char*)&a, sizeof(a));
	ofs.write((const char*)d, sizeof(c));
	ofs.write((const char*)&p, sizeof(p));
	ofs.write((const char*)c, sizeof(c));
	//5、关闭文件
	ofs.close();
}

int main() {

	test01();

	system("pause");

	return 0;
}

在这里插入图片描述



二进制文件打开是乱码
在这里插入图片描述




2.2 读文件

二进制方式读文件主要利用流对象调用成员函数read

函数原型:istream& read(char *buffer,int len);

参数解释:参数一:字符指针buffer(也可以理解为就是一段地址(指针就是地址),不过要把它强制转换成 char * ) 。它指向内存中一段存储空间。len是读写的字节数

数组名可以直接作为参数一,当传数组给一个函数时,数组类型自动转换为指针类型,传的实际是数组元素首地址。



步骤
  1. 包含头文件
  2. 创建流对象
  3. 打开文件并判断文件是否打开成功
  4. 将二进制数据转换为可读数据
  5. 打印转换后的可读数据
  6. 关闭文件


#include<iostream>
using namespace std;
// 1.包含头文件
#include <fstream>
#include <string>

class Person
{
public:
	char m_Name[64];
	int m_Age;
};

void test01()
{

	 // 2.创建流对象的同时打开文件
	ifstream ifs("person.txt", ios::in | ios::binary);

	// 3.判断文件是否打开成功
	if (!ifs.is_open())
	{
		cout << "文件打开失败" << endl;
	}

	Person p;
	
	// 4.将二进制数据转换为可读数据
	// 这一步不能将数据读出到屏幕上,这一步的作用只是把二进制数据转换为可读数据

	

	
	int d;
	int z[20];
	char c[15];
	ifs.read((char*)&d, sizeof(d));
	ifs.read((char*)z, sizeof(z));
	ifs.read((char*)&p, sizeof(p));
	ifs.read((char*)c, sizeof(c));
	

	// 5.打印转换后的可读数据
	// 用cout即可读出数据
	cout << "d=" << d << endl;
	cout << "姓名: " << p.m_Name << " 年龄: " << p.m_Age << endl;
	
	for (int i = 0; i < 20; i++) {
		cout << z[i] << endl;
	}
	for (int i = 0; i < 15; i++) {
		cout << c[i];
	}
	cout << endl;
	// 6.关闭文件
	ifs.close();

}

int main() {

	test01();

	system("pause");

	return 0;
}

在这里插入图片描述





注意事项:

  1. 把什么数据类型写入文件,查看文件时就要用相应的数据类型来接受。

比如用write函数写入一个整形数组:

  
	int c[20];
	
ofs.write((const char*)&c, sizeof(c));

那么read函数接受时也应用整形数组来接受:

int z[20];
ifs.read((char*)z, sizeof(z));


  1. 用write函数按某一顺序写入了多个数据类型时,read函数查看时也应与写入时的顺序一样

比如按下列顺序用write函数写入了以下四个数据类型:

    int a = 55;
	int d[20];
	Person p = { "张三"  , 18 };

	char c[15] = { "Hello,World!" };

	//4、按下列顺序写入文件
	ofs.write((const char*)&a, sizeof(a));
	ofs.write((const char*)d, sizeof(c));
	ofs.write((const char*)&p, sizeof(p));
	ofs.write((const char*)c, sizeof(c));





read函数查看时也得与写入时的顺序相同:

    int d;
	int z[20];
	char c1[15];
	Person p1;
// 注意各个read函数的顺序
	ifs.read((char*)&d, sizeof(d));
	ifs.read((char*)z, sizeof(z));
	ifs.read((char*)&p1, sizeof(p1));
	ifs.read((char*)c1, sizeof(c1));


不能写成下面这样:

    int d;
	int z[20];
	char c1[15];
	Person p1;
    ifs.read((char*)&d, sizeof(d));
	ifs.read((char*)c1, sizeof(c1));
	ifs.read((char*)z, sizeof(z));
	ifs.read((char*)&p1, sizeof(p1));

  • 8
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值