C++ Reading Objects from File Error
fstream file;
Patient Obj("XXX",'M',"XXX");
file.open("Patients.dat",ios::in|ios::out|ios::app);
file.seekg(ios::end);
file.write((char*)&Obj,sizeof(Obj));
file.seekg(ios::beg);
Patient x;
file.read((char*)&x,sizeof(x));
x.printallInfo();
开发者_StackOverflow
file.close();
I'm writing objects to files using this code but when i reading data VC++ 6 Crashes and thows a exception 'Access violation' .(Writing is successful)
Entire Code
#include <iostream>
#include<fstream>
#include <iomanip.h>
#include "Patient.cpp"
using namespace std;
int main(){
fstream file;
Patient Obj("XXX",'M',"XXX");
file.open("Patients.dat",ios::in|ios::out|ios::app);
file.seekg(ios::end);
file.write((char*)&Obj,sizeof(Obj));
file.seekg(ios::beg);
Patient x;
file.read((char*)&x,sizeof(x));
file.close();
return 0;
}
That seems like a brittle and non-portable way to marshal classes. One thing that could be happening with the way you do this is that you aren't making a deep copy of the data you're serializing. for instance, if one of the members of your Patient
class is a std::string
, a bare pointer is written to the file, but no string data is written. Worse, when you read that back in, the pointer points... somewhere...
A better way to deal with this issue is to actually implement a class specific method that knows exactly how to serialize and unserialize each member.
I'm not a C++ guru. Onething it doesn't seem correct here is that Object x
in your code is not initialized.
Here's how you can read and write strings:
void writestring(std::ostream & out, const std::string & s)
{
std::size_t size = s.size();
out.write((char*)&size,sizeof(size));
out << s;
}
std::string readstring(std::istream & in)
{
std::size_t size;
in.read((char*)&size,sizeof(size));
char* buf = new char[size+1];
in.read(buf,size);
buf[size] = 0;
std::string s(buf);
delete [] buf;
return s;
}
If patient has pointers (e.g. to strings as I think it does based on its constructor) then your saving saves just the pointers, not values they point to. So loading initializes pointers to places in memory which might well be deleted or moved.
ok, here is the code I could not add to the comment below
class Patient : public Person{
.....
bool savePerson(fstream& stream) const
{
// you should do to Person the same thing I did for Patient
return true;
}
bool saveMedicalDetails(fstream& stream) const
{
for(int i=0;i<5;i++)
{
stream<<mD[i].number<<endl;
// we suppose here that the strings cannot contain 'end-of-line'
// otherwise you should save before any data of a string
// the number of characters in that string, like
// stream<<mD[i].doctors_name.size()<<" "<<mD[i].doctors_name<<endl;
stream<<mD[i].doctors_name<<endl;
stream<<mD[i].diognosis<<endl;
stream<<mD[i].medicine<<endl;
stream<<mD[i].date<<endl;
}
return stream;
}
bool savePaymentDetails(fstream& stream)const
{
stream<<pD.admisson<<endl;
stream<<pD.hospital_charges<<endl;
stream<<pD.doctor_charges<<endl;
return stream;
}
bool save(fstream& stream) const
{
return savePerson(stream) ||
saveMedicalDetails(stream) ||
savePaymentDetails(stream);
}
bool loadPerson(fstream& stream)
{
// you should do to Person the same thing I did for Patient
return true;
}
bool loadMedicalDetails(fstream& stream)
{
for(int i=0;i<5;i++)
{
stream>>mD[i].number;
// we suppose here that the strings cannot contain 'end-of-line'
// otherwise you should load before any data of a string
// the number of characters in that string, like
// int size;
// stream>>size;
// char *buffer=new char[size+1];
// stream.read(buffer,size);
// *(buffer+size)=0;
// mD[i].doctors=buffer;
// delete [] buffer;
getline(stream,mD[i].doctors);
getline(stream,mD[i].diognosis);
getline(stream,mD[i].medicine);
getline(stream,mD[i].date);
}
return stream;
}
bool loadPaymentDetails(fstream& stream)
{
stream>>pD.admisson;
stream>>pD.hospital_charges;
stream>>pD.doctor_charges;
return stream;
}
bool load(fstream& stream) const
{
return savePerson(stream) ||
saveMedicalDetails(stream) ||
savePaymentDetails(stream);
}
};
I figured it out using char arrays instead of strings will solve this problem , thanks all for your great help !
精彩评论