C ++从文件错误中读取对象

时间:2010-10-23 06:02:44

标签: c++ visual-c++

        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 个答案:

答案 0 :(得分:2)

这似乎是一种脆弱且不可移植的编组课程的方法。您执行此操作的方式可能发生的一件事是您没有对要序列化的数据进行深层复制。例如,如果Patient类的一个成员是std::string,则将裸指针写入文件,但不写入任何字符串数据。更糟糕的是,当你读回来时,指针指向...某处......

处理此问题的更好方法是实际实现一个特定于类的方法,该方法确切地知道如何序列化和反序列化每个成员。

答案 1 :(得分:1)

我不是C ++专家。这里似乎不正确的是你的代码中的对象x没有被初始化。

答案 2 :(得分:1)

如果患者有指针(例如我认为它基于其构造函数的字符串),那么您的保存只保存指针,而不是它们指向的值。因此,加载初始化指向内存中可能被删除或移动的位置的指针。

好的,这是我无法添加到下面评论中的代码

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

答案 3 :(得分:1)

以下是阅读和编写字符串的方法:

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

答案 4 :(得分:0)

我认为使用char数组而不是字符串会解决这个问题,谢谢大家的帮助!