如何在c+中从二进制文件中写入和读取类+; 我在C++中学习FStand,ID喜欢用二进制写一个类,然后再检索它。当然,这一切都出了可怕的问题

如何在c+中从二进制文件中写入和读取类+; 我在C++中学习FStand,ID喜欢用二进制写一个类,然后再检索它。当然,这一切都出了可怕的问题,c++,class,binary,fstream,C++,Class,Binary,Fstream,上课时间到了 class Student { private: const char* name; int age; public: Student() { }; Student(const char* name, int age) : name{ name }, age{ age }{}; void display() { std::cout << "name : " << this-&g

上课时间到了

class Student
{
private:
    const char* name;
    int age;
public:
    Student()
    {

    };
    Student(const char* name, int age) : name{ name }, age{ age }{};
    void display()
    {
        std::cout << "name : " << this->name << std::endl << "age : " << this->age << std::endl;
    }
};
班级学生
{
私人:
常量字符*名称;
智力年龄;
公众:
学生()
{
};
学生(const char*name,int age):name{name},age{age};
无效显示()
{

std::cout这里的问题不是您从磁盘读取或写入的字节不正确。相反,您遇到的问题是这些字节并不是您想要的意思

您的类有一个数据成员
name
,它是一个
const char*
。它是指向内存中某个包含该名称的位置的指针。当您使用
write
函数将数据从您的类型写入磁盘时,它将该指针存储在磁盘上的某个位置。然后从磁盘加载数据时,它将重新加载该点呃

问题是指针不是您想要存储的。如果您从磁盘重新加载指针,它将指向内存中与以前相同的位置,但没有理由怀疑您会在其指向的位置的内存中找到该学生的姓名。如果您关闭该程序,然后重新打开它,则不应该看到任何内存从上一次运行中恢复

要解决此问题,您需要更改将数据写入磁盘的方式。与其从类中复制原始字节,不如看看是否可以找到一种方法来写出名称和年龄,然后以某种方式读回该数据。例如,您可能会将其作为年龄、空间和名称写入磁盘


希望这能有所帮助!

这里的问题不是您从磁盘读取或写入的字节不正确。相反,您遇到的问题是这些字节并不是您想要的意思

您的类有一个数据成员
name
,它是一个
const char*
。它是指向内存中某个包含该名称的位置的指针。当您使用
write
函数将数据从您的类型写入磁盘时,它将该指针存储在磁盘上的某个位置。然后从磁盘加载数据时,它将重新加载该点呃

问题是指针不是您想要存储的。如果您从磁盘重新加载指针,它将指向内存中与以前相同的位置,但没有理由怀疑您会在其指向的位置的内存中找到该学生的姓名。如果您关闭该程序,然后重新打开它,则不应该看到任何内存从上一次运行中恢复

要解决此问题,您需要更改将数据写入磁盘的方式。与其从类中复制原始字节,不如看看是否可以找到一种方法来写出名称和年龄,然后以某种方式读回该数据。例如,您可能会将其作为年龄、空间和名称写入磁盘


希望这有帮助!

提前感谢,错误是读访问冲突:)在序列化和反序列化时读取。您不能将任何类原始字节写入文件并将其读回。尤其是当它包含指针或引用成员或复杂类(如
std::list
等)时。写入类(我认为这是可行的)--不,它不是。你正在写一个指向文件的指针值。如果你打开文件,你会发现“jack”这个词不见踪影,而是垃圾。
age
可以,因为它是POD(普通的旧数据)。任何复杂变量,包括指针另一端的动态变量,都不是结构的一部分,因此不会保存。@Dems314您需要写入类表示的数据,而不是对象的原始字节。“名称”表示字符,因此您以某种方式写入字符数据,以便在读取时可以重新创建对象。如果您有一个表示棋盘的
char**
,您是否认为写入双指针会将棋局状态保存到文件中?当然不会,您需要更多。这就是序列化的要点关于on和反序列化。提前感谢,错误是读访问冲突:)在序列化和反序列化时读取。您不能将任何类原始字节逐个写入文件并将其读回。尤其是当它包含指针或引用成员或复杂类(如
std::list
等)时。写入类(我认为这是可行的)--不,它不是。你正在写一个指向文件的指针值。如果你打开文件,你会发现“jack”这个词不见踪影,而是垃圾。
age
可以,因为它是POD(普通的旧数据)。任何复杂变量,包括指针另一端的动态变量,都不是结构的一部分,因此不会保存。@Dems314您需要写入类表示的数据,而不是对象的原始字节。“名称”表示字符,因此您以某种方式写入字符数据,以便在读取时可以重新创建对象。如果您有一个表示棋盘的
char**
,您是否认为写入双指针会将棋局状态保存到文件中?当然不会,您需要更多。这就是序列化的要点我的天哪,我从来没有想过,我把名字字段完全删除,保存了年龄,阅读工作。我需要一些书。不用担心!C++是一个有很多移动部分的语言,从一个流中写/读数据需要一些练习,即使你知道你在做什么。我的天哪,THA。我甚至从来没有想过,我把名字字段完全删除,保存了年龄,阅读工作。我需要一些书。不用担心!C++是一个有很多移动部分的语言,从一个流中写/读数据需要一些练习,即使你知道你在做什么。
void writeDatabase()
{
    Student jack("jack", 21);
    std::ofstream file;
    file.open("data.dat", std::ios::binary);
    if (file.is_open())
    {
        file.write(reinterpret_cast<char*>(&jack), sizeof(jack));
        std::cout << "wrote to file";
    }
    else
    {
        std::cout << "error opening file when writing to database\n";
    }
    file.close();
}
void readData()
{
    Student st;
    std::ifstream file;
    file.open("data.dat", std::ios::binary);
    if (file.is_open())
    {
        std::cout << "opened file\n";
        file.read(reinterpret_cast<char*>(&st), sizeof(st));
        st.display();
        file.close();
    }
    else
    {
        std::cout << "error opening file when reading\n";
    }
}