从二进制数据中读取对象

时间:2012-08-11 18:38:43

标签: c++ binary

我一直在从二进制文件中读取一组SRD对象 - 但由于这是我第一次这样做,所以我修改了一个标题,使其所有成员都公开,因为我不知道会发生什么。我已经完成了我的任务,剩下的就是将这些成员设为私有,并编写修改它们的方法。但是,有一个问题。 出于调试目的,我只将1个成员私有,直到我为它编写所有方法,我将保持这种方式。这个成员只是一个unsigned int C.当写一个返回它的方法(getC()返回C)时,它返回的值为0000 ... 3435973836,这意味着它没有设置? 所以,我有一个基于二进制文件中对象数量创建的SRD指针数组。

SRD *a;
...
a = new SRD[numOfRecords];

并从文件中填充数组...

for (i=0; i<numOfRecords; i++)
    {
        f.seekg(i * sizeof s);  
        f.read((char *)&a[i], sizeof s);
        cout << a[i].getCC();
    }

现在,a[i].getCC()在C公开时起作用,但是将其设为私有会使000..3435 ... 意味着访问它不是问题,但它没有设置在前一个for循环的fread中。我想我需要一些类型的赋值运算符,它设置这些值,但我没有线索...

2 个答案:

答案 0 :(得分:1)

当您将变量设为私有时,SRD类不再是plain old data (POD)。因此,您无法保证其内存中的表示形式,因此您不能再依赖f.read这样的工作了。

我建议您在类中和该方法中添加一个read-from-stream方法,read直接添加到unsigned int成员变量中。然后,在循环中,您只需调用该方法(将流作为引用或指针传递)。

编辑,请求示例:

class SRD {
  ...
  public:
    void readFromStream(istream& f) {
      f.read(&CC, sizeof CC);
    }
  private:
    unsigned int CC;
};

循环:

for (i=0; i<numOfRecords; i++)
{
    a[i].readFromStream(f);
    cout << a[i].getCC();
}

答案 1 :(得分:0)

实际上,问题还有其他问题:标题按特定顺序定义,第一个成员是数组,而C是第二个,而调试时我首先使用C - 并将其从第二个位置移开对于上述公众,改变了班级的结构。

所以,

Class P
{
int i;
char c;
}

不同
Class P
{
char c;
int i;
}

因为二进制文件中的数据具有特定顺序,并且在重新排列类别防御的顺序时,成员(c)尝试访问用于其他成员的数据(i)