0
        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();

        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;


}

7
  • 3
    You need to show the declaration of Patient. Are you sure you're not writing pointers instead of complete strings into the file? Commented Oct 23, 2010 at 6:06
  • I suspect the problem is in your printallInfo function. What's that look like? Commented Oct 23, 2010 at 6:18
  • Hey..i didnt got what u were telling :) Commented Oct 23, 2010 at 6:19
  • can you show us the Patient class implementation? We need to see Patient.cpp, BTW, including a source file is generally a very bad idea.. Commented Oct 23, 2010 at 6:23
  • Reading this might help: parashift.com/c++-faq-lite/serialization.html#faq-36.6 Got any strings in Patient? Commented Oct 23, 2010 at 6:25

5 Answers 5

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

sorry, I didn't see your comment before posting mine
1

I'm not a C++ guru. Onething it doesn't seem correct here is that Object x in your code is not initialized.

1 Comment

I'm Calling the default constructor !. Do you have any other idea now to initialize it ?
1

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

Comments

1

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

7 Comments

strings like char* or like std:string?
std:string are there can you please tell me to overcome this ? thanks !
I will try. First and most important: if you have strings, reading on from the file to the memory allocated for these objects will simply set them to random. One approach will be to add a method to Patient for saving and one for loading where the members of Patient will be saved (and loaded) one at a time. If the members are not simple in structure (i.e. not int, float, e.t.c.) you must provide methods to save the too. I suggest you post the structure of Patient
ok, I don't have a c++ compiler handy right now, so I only wish this compiles. Ok, I posted to code to the answer (I could not post it in a comment)
thanks a lot ill go though this ! :D .. will i face any prob while reading the object from the file?
|
0

I figured it out using char arrays instead of strings will solve this problem , thanks all for your great help !

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.