【问题标题】:c++ append a struct into a binary filec ++将结构附加到二进制文件中
【发布时间】:2011-10-13 08:57:35
【问题描述】:

我有我的结构:

struct a
{
  int    x;
  float  f;
  double d;
  char   c;
  char   s[50];
};

我希望每次都将我的计时器时间表附加到一个二进制文件中。

// declaration
std::ofstream outFile;

// constructor:
outFile.open( "save.dat", ios::app );

// tick:
outFile << a << endl;

但是在 save.dat 里面只出现了这个:

0C3A0000..0C3A0000..0C3A0000..0C3A0000..0C3A0000..0C3A0000..0C3A0000..0C3A0000..0C3A0000..

提前致谢

【问题讨论】:

  • 你给我们完整的代码吗?您可能只是在打印指针值。您必须重载&lt;&lt; 运算符,或者编写一些序列化代码。

标签: c++ file struct append


【解决方案1】:

您当前正在做的是写入结构定义的地址。
你想做的是使用ostream::write

outfile.write(reinterpret_cast<char*>(&myStruct), sizeof(a));

只要您的结构是 POD(普通旧数据)类型(您的示例就是),这将起作用。 POD 类型意味着所有成员都是固定大小的。

另一方面,如果您有可变大小的成员,那么您需要一个一个地写出每个成员。

【讨论】:

  • 这可能仍然不是一个好主意,因为该结构将具有平台相关的填充...
  • @ghiboz:为什么你认为你在使用 ios:app 时会覆盖它?
【解决方案2】:

序列化自定义对象的明智方法是重载您自己的输出流运算符:

std::ostream & operator<<(std::ostream & o, const a & x)
{
  o.write(reinterpret_cast<char*>(&x.x), sizeof(int));
  o.write(reinterpret_cast<char*>(&x.f), sizeof(float));
  /* ... */
  return o;
}

a x;
std::ofstream ofile("myfile.bin", std::ios::binary | std::ios::app);
ofile << a;

这仍然依赖于平台,所以为了更安全一点,您可能应该使用固定宽度的数据类型,如int32_t 等。

在语义上使用&lt;&lt; 进行二进制输出可能也不是最好的主意,因为它通常用于格式化 输出。也许更安全的方法是编写一个函数void serialize(const a &amp;, std::ostream &amp;);

【讨论】:

  • 可能仍然不是一个好主意,因为你有小/大端系统......
  • 当然,您必须根据自己的需要进行设计……这一切都取决于。如果您在 x86/x64 服务器群(如 Facebook)中并且需要高吞吐量,您可能会认为这是一种有效但范围有限的解决方案;如果你想超级独立于平台,你必须精确地记录二进制格式。这一切都取决于您的需求! (如果你愿意,你也可以讨论浮点序列化这个话题......这真的取决于。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-11
  • 1970-01-01
  • 2020-10-07
  • 1970-01-01
  • 2011-05-08
  • 1970-01-01
  • 2013-05-31
相关资源
最近更新 更多