【问题标题】:Writing/reading structure to/from binary file in c++在c ++中向/从二进制文件写入/读取结构
【发布时间】:2012-05-16 03:27:16
【问题描述】:

我正在构建一个数据库工具,我要做的就是将一个结构写入二进制文件,然后再次读取它。以下是我可以在网上找到的最接近的方法,但它存在重大问题:

#include <fstream>
#include <iostream>
#include <vector>
#include <string.h>

using namespace std;


typedef struct student
{
    char name[10];
    int age;
    vector<int> grades;
}student_t;

int main()
{
    student_t apprentice[3];  
    strcpy(apprentice[0].name, "john");
    apprentice[0].age = 21;
    apprentice[0].grades.push_back(1);
    apprentice[0].grades.push_back(3);
    apprentice[0].grades.push_back(5);    

    strcpy(apprentice[1].name, "jerry");
    apprentice[1].age = 22;
    apprentice[1].grades.push_back(2);
    apprentice[1].grades.push_back(4);
    apprentice[1].grades.push_back(6);

    strcpy(apprentice[2].name, "jimmy");
    apprentice[2].age = 23;
    apprentice[2].grades.push_back(8);
    apprentice[2].grades.push_back(9);
    apprentice[2].grades.push_back(10);

    // Serializing struct to student.data
    ofstream output_file("students.data", ios::binary);
    output_file.write((char*)&apprentice, sizeof(apprentice));
    output_file.close();

    // Reading from it
    ifstream input_file("students.data", ios::binary);
    student_t master[3];
    input_file.read((char*)&master, sizeof(master));   

    apprentice[0].grades[0]=100; // ALTERING THE INPUT STRUCTURE AFTER WRITE

    for (size_t idx = 0; idx < 3; idx++)
    {
        // If you wanted to search for specific records, 
        // you should do it here! if (idx == 2) ...

        cout << "Record #" << idx << endl;
        cout << "Name: " << master[idx].name << endl;
        cout << "Age: " << master[idx].age << endl;
        cout << "Grades: " << endl;
        for (size_t i = 0; i < master[idx].grades.size(); i++)
           cout << master[idx].grades[i] << " ";
        cout << endl << endl;
    }

    return 0;
}

这似乎是在写入文件,读回文件,然后打印到屏幕上,但不幸的是:首先,程序在尝试关闭时因调试断言失败(dbgdel.cpp 第 52 行)而崩溃,其次,更改了 input 写入后的结构(正如我在示例中所做的那样)改变了所谓的读取结构。我猜正在发生的事情是不知何故“数据”和“inData”是同一件事(这可以解释崩溃,因为它会尝试从内存中删除同一件事两次)。谁能得到这个工作?我已经尝试了所有我能想到的。

【问题讨论】:

标签: c++ serialization binary structure ifstream


【解决方案1】:

问题在于您的结构是动态的(由于矢量)。这总是会使事情复杂化,因为您实际上是在存储一个 char *。向量是一个复杂的数据结构。您不能只将其屏蔽为 char * 并期望它代表元素。所以你甚至没有存储你需要的东西。 我建议您将向量更改为 int grades[NO_OF_SUBJECTS] 之类的东西。这应该可以正常工作。

【讨论】:

  • 务必将数组初始化为全零。
【解决方案2】:

你需要知道的事情:

你对vector做的push_backs不会增加sizeof(apprentice)。 向量不是线性嵌套在结构内,向量在内部分配内存。您可以将矢量对象(以及许多其他 STL 容器对象)视为指针之类的东西。

您需要使用固定大小的数组而不是向量。

或者,您可以将每个矢量组件转储到文件中,并在您读回它们时使用push_backs 解析它们。

【讨论】:

    【解决方案3】:

    正如其他人指出的那样,vector 更像是一个指针,所以sizeof 不起作用。您要么必须使用具有固定等级数的静态 C 数组(sizeof 在那里工作),要么您必须通过编写 `grades.size( ) 为每个学生归档,然后写下每个成绩。

    那么当你回读时,你会:

    1. 读名字
    2. 阅读年龄
    3. 读取等级数
    4. 知道要阅读多少个年级,阅读每个年级并推送给您的学生

    您还可以通过 null 终止和沿读取字符微动直到您点击 '\0' 来允许可变大小的名称,或者您可以序列化名称长度并如上所述读取它。

    这比你上面的更乏味。但是您需要以灵活性换取复杂性。

    【讨论】:

      猜你喜欢
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多