我有读取文件的基本文件处理代码,名为" student.dat"使用visual studio。
输出读取文件并在控制台中显示结果,但visual studio会弹出对话框
代码:
#include<iostream>
#include<fstream>
#include<conio.h>
#include<string>
using namespace std;
class student
{
int admno;
// char name[20];
string name;
public:
void getdata()
{
cout<<"\n\nEnter The Name of The Student ";
//gets(name);
cin>>name;
getch();
cout<<"\nEnter The admission no. ";
cin>>admno;
// getch();
}
void showdata()
{
cout<<"\nAdmission no. : "<<admno;
cout<<"\nStudent Name : ";
cout<<name;
//puts(name);
}
int retadmno()
{
return admno;
}
};
int main()
{
student obj;
ifstream fp1;
fp1.open("student.dat",ios::binary);
while(fp1.read((char*)&obj,sizeof(obj)))
{
obj.showdata();
}
fp1.close();
return 0;
}
答案 0 :(得分:3)
您只能将原始数据加载到某些POD对象。这一行是错误的:
fp1.read( (char*)&obj,sizeof(obj) );
因为student
包含std::string
。 std::string
包含一个指向内存块的指针,该内存块在对象被销毁后变为无效且完全无用。这意味着您加载到std::string
的数据只是垃圾。
我会考虑对象序列化。 Boost serialization是一个很好的开始方式。
答案 1 :(得分:2)
您尝试将对象存储/加载到文件,该文件无效。
while(fp1.read((char*)&obj,sizeof(obj)))
对象可能包含对加载后无效的内存(std :: string eg)的引用。您必须为对象提供序列化,或使用没有指针或引用的纯结构来存储数据。 E.g:
struct {
int admno;
char[20] name;
}
如果需要长度可变的字符串,可以使用字符串存储:
struct {
int admno;
size_t name_index;
}
std::vector<std::string> names;
要存储,迭代您的姓名并保存每个.c_str
的长度和std::string
。要读取,请执行相反的操作并将长度读入n,将n个字节读入缓冲区并从缓冲区构造std::string
。
您可以查看http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/index.html
答案 2 :(得分:0)
您永远不会致电GetData
,因此admno
中未ShowData
实例化{{1}}