C ++ Чтение объектов из файла Ошибка - PullRequest
0 голосов
/ 23 октября 2010
        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();

Я пишу объекты в файлы, используя этот код, но при чтении данных VC ++ 6 вылетает и выдает исключение «Нарушение прав доступа» (запись успешна)

Весь код

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


}

Ответы [ 5 ]

2 голосов
/ 23 октября 2010

Это похоже на хрупкий и непереносимый способ маршалинга. То, что может случиться с вами, заключается в том, что вы не делаете глубокую копию сериализуемых данных. например, если один из членов вашего Patient класса является std::string, пустой указатель записывается в файл, но строковые данные не записываются. Хуже того, когда вы читаете это обратно, указатель указывает ... где-то ...

Лучшим способом решения этой проблемы является реализация метода, специфичного для класса, который точно знает, как сериализовать и десериализовать каждый член.

1 голос
/ 23 октября 2010

Вот как вы можете читать и писать строки:

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;
}
1 голос
/ 23 октября 2010

Если у пациента есть указатели (например, на строки, как я думаю, на основе своего конструктора), то при сохранении сохраняются только указатели, а не значения, на которые они указывают.Таким образом, загрузка инициализирует указатели на места в памяти, которые вполне могут быть удалены или перемещены.

хорошо, вот код, который я не мог добавить к комментарию ниже

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);
}
};
1 голос
/ 23 октября 2010

Я не гуру C ++.Это кажется неправильным, так как объект x в вашем коде не инициализирован.

0 голосов
/ 23 октября 2010

Я понял это, используя массивы символов вместо строк, чтобы решить эту проблему, спасибо всем за вашу большую помощь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...