【C++基础】面向对象方法(十二)

文章详细讲解了C++中的面向对象方法,包括一系列的教程内容。同时,介绍了文件的随机读写操作,如使用seekg()和seekp()函数定位文件指针,以及tellg()和tellp()获取文件指针位置。此外,文章还讨论了如何为用户自定义数据类型重载输入输出运算符>>和<<,以便更方便地处理自定义类型的数据输入输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

系列文章目录

【C++基础】面向对象方法(一)
【C++基础】面向对象方法(二)
【C++基础】面向对象方法(三)
【C++基础】面向对象方法(四)
【C++基础】面向对象方法(五)
【C++基础】面向对象方法(六)
【C++基础】面向对象方法(七)
【C++基础】面向对象方法(八)
【C++基础】面向对象方法(九)
【C++基础】面向对象方法(十)
【C++基础】面向对象方法(十一)



一、文件的随机读写

有些情况下,需要从文件某个位置开始进行读/写操作。例如,要更改一名学生的信息,就需要先将文件指针定位到正确位置,再进行写操作;要查询某名学生的信息,也需要先将文件指针定位到正确位置,再进行读操作。与顺序读/写相对应,这种非顺序读/写称为随机读/写。
seekg()函数和seekp()函数分别用于定位输入文件流对象和输出文件流对象的文件指针,函数原型分别为:

								istream& seekg(long offset,seek_dir origin=ios::beg);
								ostream& seekp(long offset,seek_dir origin=ios::beg);

函数的功能是文件指针从参照位置origin开始移动offset个字节。

参数offset是长整型,表示文件指针相对参照位置偏移的字节数,取值为正表示向后移动文件指针,取值为负则表示向前移动文件指针。
参数origin则为参照位置,seek_dir是系统定义的枚举类型,有以下3个枚举常量:ios::beg:文件首 ios::cur:文件指针当前位置 ios::end:文件尾

假设infile是ifstream类的对象,outfile是ofstream类的对象,将infile的文件指针从当前位置向前移5个字节:
infile.seekg(-5,ios::cur);
将outfile的文件指针从文件首向后移5个字节:
outfile.seekp(5,ios::beg);

在进行文件的随机读/写时,还可使用tellg()和tellp()函数获取文件指针的当前位置。tellg()是输入文件流对象的成员函数,tellp()是输出文件流
对象的成员函数,它们的函数原型分别为:
streampos tellg();
streampos tellp();
提示:对于fstream对象,则既可使用seekg()和tellg()函数,也可使用seekp()和tellp()函数,结果完全一样。

例1:将3名学生的学号、姓名和成绩写入二进制文件studentinfo.dat中,再将第2名学生的成绩改为627。从文件中读取第m(m的值由用户从键盘输入)名学生的信息并将其输出到屏幕上。

代码如下(示例):

#include<iostream>
#include<fstream>
using namespace std;
struct Student //Student结构体类型定义
{
	char num[10];
	char name[20];
	int score;
};
int main()
{
	Student stu[3] =
	{
		{"1210101","张三",618},
		{"1210102","李四",625},
		{"1210103","王五",612}
	};
	int i,m;
	fstream outfile("studentinfo1.dat", ios::binary | ios::out);
	if (!outfile.is_open()) //判断文件打开操作是否成功
	{
		cout << "打开文件studentinfo.dat失败!" << endl;
		return 0;
	}
	for (i = 0; i < 3; i++) //将第i名学生的数据写入文件
		outfile.write((char*)&stu[i], sizeof(Student));
	outfile.close(); //关闭文件
	fstream myfile;
	myfile.open("studentinfo1.dat",ios::binary|ios::in|ios::out);
	if (!myfile.is_open())
	{
		cout << "打开文件studentinfo.dat失败!" << endl;
		return 0;
	}
	stu[1].score = 627;
	//将文件指针定位到第2名学生
	myfile.seekp(1 * sizeof(Student), ios::beg);
	//用新数据覆盖原来文件中保存的第2名学生的数据
	myfile.write((char*)&stu[1], sizeof(Student));
	cout << "请输入待查询的学生序号(1-3):";
	cin >> m;
	if (m < 1 || m>3)
	{
		cout << "学生不存在!" << endl;
		return 0;
	}
	//将文件指针定位到第m名学生数据开始的位置
	myfile.seekg((m - 1) * sizeof(Student), ios::beg);
	//将指定学生的数据读入到内存中
	myfile.read((char*)&stu[m - 1], sizeof(Student));
	cout << "第" << m << "名学生的学号、姓名和成绩:"
		<< stu[m - 1].num << ","
		<< stu[m - 1].name << ","
		<< stu[m - 1].score << endl;
	myfile.close(); //关闭文件
	return 0;
}

二、用户自定义数据类型的输入输出

C++输入/输出流类库中对提取运算符">>“和插入运算符”<<“进行了多次重载,它们能够实现多种内部类型数据的输入输出操作。例如:输入流对象in和输出流对象out调用重载运算符函数实现数据的输入/输出。 int x; in>>x;等价于in.operator>>(x); out<<x;等价于out.operator<<(x);
如果对用户自定义类型的数据也希望能直接使用”>>“和”<<"进行输入/输出,必须由编程人员对它们进行重载。
重载的函数形式为:
istream& operator>>(istream&,自定义类型&);
ostream& operator<<(ostream&,自定义类型&);

代码如下(示例):

#include<iostream>
#include<fstream>
using namespace std;

struct Student
{
	char num[10];
	char name[20];
	int score;
};
//">>"运算符重载函数
istream& operator>>(istream& in, Student& stu)
{
	in >> stu.num >> stu.name >> stu.score;
	return in;
}
//"<<"运算符重载函数
ostream& operator<<(ostream& out, Student& stu)
{
	out << stu.num << ' ' << stu.name << ' ' << stu.score << endl;
	return out;
}
int main()
{
	Student stu[3] =
	{
		{"1210101","张三",618},
		{"1210102","李四",625},
		{"1210103","王五",612}
	};
	int i;
	fstream outfile("studentinfo.txt", ios::out);
	if (!outfile.is_open()) //判断文件打开操作是否成功
	{
		cout << "打开文件失败!" << endl;
		return 0;
	}
	for (i = 0; i < 3; i++)
		outfile << stu[i];//调用operator<<(outfile,stu[i]);
	outfile.close();//关闭文件
	
	fstream infile("studentinfo.txt", ios::in);
	if(!infile.is_open()) //判断文件打开操作是否成功
	{
		cout << "打开文件失败!" << endl;
		return 0;
	}
	//将第i名学生的数据读入到内存中
	for (i = 0; i < 3; i++)
		infile >> stu[i];
	for (i = 0; i < 3; i++)
	{
		cout << "第" << i + 1 << "名学生的学号、姓名和成绩:";
		cout << stu[i];//调用operator<<(cout,stu[i]);
	}
	infile.close();//关闭文件
	return 0;
}
/*提示:还可以为文件流单独编写重载函数,用二进制文件存储学生信息。*/
fstream& operator<<(fstream& outfile, Student& stu)
{
	outfile.write((char*)&stu,sizeof(stu));
	return outfile;
}
fstream& operator<<(fstream& infile, Student& stu)
{
	infile.write((char*)&stu, sizeof(stu));
	return infile;
}

总结

以上就是今天记录的内容,本文仅仅简单介绍了文件的随机读写、用户自定义数据类型的输入输出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值