保存含string 成员的结构体或类到文件中的注意事项

将结构体信息保存到文件中时,需要特别注意以下两点:

1. 最好不要将动态申请的地址(包括string 类)直接保存到文件中。

2. 如果设计的结构体中存在指针变量,并且需要保存结构体信息,那么不但需要保存结构体,而且保存指针指向的内容。


例如:

struct Book{
string title;
double price;
string author;
};

如果直接保存该结构体到文件中,那么在读取的时候程序很可能会出问题。

错误例子如下:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>


int main()
{
using namespace std;
struct Book{
string title;
double price;
string author;
};

Book wbook;
ofstream fout;
fout.open("book.dat", ios_base::out|ios_base::trunc);
if(!fout.is_open())
{
cout << "open error!";
exit(1);
}
cout << "Enter the book title: ";
getline(cin, wbook.title);
cout << "Enter the book's price: $";
cin >> wbook.price;
cin.get();
cout << "Enter the book's author: ";
getline(cin, wbook.author);

//将结构体保存到文件中
fout.write((char *)&book, sizeof(Book));
fout.close();


//从文件中读取结构体的内容

Book rbook;
ifstream fin("book2.dat", ios_base::in);
fin.read((char *)&rbook, sizeof(Book));
cout << "title: " << rbook.title << endl;
cout << "price: $" <<r book.price << endl;
cout << "author: " << rbook.author << endl;
fin.close();


return 0;
}


运行结果是段错误。

主要原因是: 将book保存到文件中时,并没有把其中string类指向的字符串保存,而仅仅保存了string动态申请存储字符串的地址。

程序有2个问题:

1. 因为保存的是动态申请的地址, 程序再次运行时,文件中保存的动态地址没有任何意义。

2. 在程序读取文件后由于定义了wbook 和 rbook 两个变量, 其中的string 类保存的是相同的地址, 因此在变量生命周期结束后,将会释放相同的地址两次, 导致段错误。


修改方法:

1. 可以使用数组保存 title, 和author,这样不会有任何问题。

2. 读取文件内容时同样读取到wbook 变量中 ,也就是说不要定义两个变量, 这样就只会释放动态内存一次,但是这样只能保证程序单独一次运行正常, 保存的数据无任何意义。 


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值