繁体   English   中英

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

[英]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();

        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;


}

这似乎是上课的一种脆弱且不方便的方式。 执行此操作可能会发生的一件事是,您没有对要序列化的数据进行深入复制。 例如,如果Patient类的成员之一是std::string ,则将裸指针写入文件,但不写入字符串数据。 更糟糕的是,当您读回该内容时,指针指向...某处...

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

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

如果患者有指针(例如,根据我的想法基于其构造函数指向字符串),则您的保存操作将仅保存指针,而不保存指针指向的值。 因此,加载会初始化指向内存中可能被删除或移动的位置的指针。

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

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

这是读取和写入字符串的方法:

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

我发现使用char数组而不是字符串可以解决此问题,谢谢大家的大力支持!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM