以二进制格式读取类

时间:2018-05-17 14:25:44

标签: c++ binary

我正试图以二进制格式读取我的类:

FILE* file = fopen(filePath.toStdString().c_str(), "rb");
if (file == NULL)
{
    QMessageBox::critical(this, "Ошибка!", "Ошибка при открытии файла!");
    return;
}

while (!feof(file))
{
    Dog* dog;
    fread(dog, sizeof(Dog), 1, file);
    _list->emplace_back(dog);
}
fclose(file);

但是我收到一个错误:程序崩溃了。该文件存在,数据写如下:

FILE* file = fopen(filePath.toStdString().c_str(), "wb");
if (file == NULL)
{
    QMessageBox::critical(this, "Ошибка!", "Ошибка при открытии файла!");
    return;
}

for (int i = 0; i < _list->size(); i++)
{
    fwrite(_list->get(i), sizeof(Dog), 1, file);
}
fclose(file);

此代码运行没有错误。请帮助:(

2 个答案:

答案 0 :(得分:0)

尝试此更正:

std::ifstream data_file("my_dogs.dat", ios::binary);
Dog d;
std::vector<Dog> database;
while (data_file.read((char *) &d, sizeof(Dog)))
{
  database.push_back(d);
}

在上面的片段中,我使用C ++流打开文件。 混合C ++和C风格的流是一个坏主意。

循环基于从流中读取的成功。如果读取失败,则循环终止。

将数据读入局部变量,然后附加到数据库。无需分配内存,因为std::vector会将副本附加到容器中。

您可以将std::list替换为std::vector,但可以使用适当的方法附加到列表中。

在互联网上搜索&#34; C ++序列化&#34;和&#34; C ++ QT序列化&#34;欲获得更多信息。

答案 1 :(得分:0)

实际上问题是Dog类包含一个字段QString,没有程序知道要读取多少字节(字符串"asd""asdasdasdasdasdasdsad"返回不同的syzeof )。因此错误。做一些事情是正确的:

    FILE* file = fopen(filePath.toStdString().c_str(), "rb");

    while (!feof(file))
    {
        int nameSize;
        QString name;
        int breedSize;
        QString breed;
        int weigth;
        QDate birthDate;

        fread(&nameSize, sizeof(int), 1, file);
        for (int i = 0; i < nameSize; i++)
        {
            QChar ch;
            fread(&ch, sizeof(QChar), 1, file);
            name += ch;
        }

        fread(&breedSize, sizeof(int), 1, file);
        for (int i = 0; i < breedSize; i++)
        {
            QChar ch;
            fread(&ch, sizeof(QChar), 1, file);
            breed += ch;
        }

        fread(&weigth, sizeof(int), 1, file);
        fread(&birthDate, sizeof(QDate), 1, file);
        _list->emplace_back(new Dog(name, breed, weigth, birthDate));
   }
   fclose(file);