【问题标题】:How to write and read class from binary file in c++如何在 C++ 中从二进制文件中写入和读取类
【发布时间】:2020-03-16 18:08:46
【问题描述】:

我正在学习 c++ 中的 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->name << std::endl << "age : " << this->age << std::endl;
    }
};

写作课(我认为有效)

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

【问题讨论】:

  • 提前谢谢,错误是读取访问冲突:)
  • 阅读序列化反序列化。您不能仅将任何类原始字节逐字节写入文件并将其读回。特别是如果它包含指针或引用成员或复杂类,如std::list 等。
  • 写作类(我认为有效) -- 不,它没有。您正在将指针值写入文件。如果你打开文件,你会发现“jack”这个词已经找不到了,而是垃圾。
  • age 没问题,因为它是 POD(普通旧数据)。任何复杂变量,包括指针另一端的动态变量,都不是结构的一部分,因此不会被保存。
  • @Dems314 您需要编写类所代表的数据,而不是对象的原始字节。 “名称”表示字符,因此您以某种方式写入字符数据,以便在读入时可以重新创建对象。如果您有一个代表棋盘的char **,您是否认为写入双指针可以保存状态国际象棋游戏到文件?当然不是——你需要的还不止这些。这就是序列化和反序列化的要点。

标签: c++ class binary fstream


【解决方案1】:

这里的问题不在于您错误地从磁盘读取或写入字节。相反,您遇到的问题是这些字节并不意味着您想要它们的意思。

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

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

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

希望这会有所帮助!

【讨论】:

  • 我的天哪,我从来没有想过,我完全删除了姓名字段并保留了年龄,并且阅读作品。我需要一些书。
  • 别担心! C++ 是一种包含许多移动部件的语言,即使您知道自己在做什么,从流中写入/读取数据也需要一些练习。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-26
  • 1970-01-01
  • 2012-05-16
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多