【问题标题】:Reading double from binary files从二进制文件中读取双精度
【发布时间】:2014-04-11 10:05:02
【问题描述】:

需要格式化,编辑需要一些时间。

【问题讨论】:

  • 最好使用sizeof(double)而不是常量8。
  • 你确定 test.txt 是二进制的吗?
  • 你说每行但以二进制模式打开文件,听起来这就是问题所在。文件内容是使用文本编辑器创建的,还是您在其中写入了二进制双精度值?

标签: c++ file binary double


【解决方案1】:

使用fin >> d 和使用fin.read 阅读会做不同的事情。由于fin >> d 有效,您似乎有一个文件,其中写入了双精度的字符串表示。使用fin.read 表明您的文件是用二进制编写的,但似乎并非如此。此外,您最好使用sizeof(double),而不是硬编码常量8

【讨论】:

  • 文件是使用 write 函数写入的。
  • @user2806369 当你打开文件时(例如在文本编辑器中)你能读取它的内容吗?
  • 当使用 >> 运算符时,它是记事本可读的(英语很糟糕)。
  • @user2806369 我的意思是您尝试使用>>read 可读的文件。你能读取你存储在其中的双精度值吗?
  • @user2806369 如果文件是用二进制编写的,那么在 notepad++ 中打开它也无济于事,因为它的内容不适合人类阅读。因此,我认为文件不是以二进制形式编写的理论似乎是正确的。
【解决方案2】:

问题是你误解了std::ifstream::read 函数的语义。根据 C++ 参考:

注意:此文档适用于 std::istream,但适用于 ifstream

std::istream::operator>>()

应用于输入流的这种运算符 (>>) 称为提取运算符。它作为成员函数被重载:

arithmetic types

从流中按顺序提取和解析字符以将它们解释为适当类型的值的表示,该值存储为 val 的值。 在内部,该函数通过首先构造一个哨兵对象(将 noskipws 设置为 false)来访问输入序列。然后(如果好的话),它调用 num_get::get (使用流的选定语言环境)来执行提取和解析操作,相应地调整流的内部状态标志。最后,它在返回之前销毁哨兵对象。

stream buffersmanipulators

而对于std::istream::read

这个函数只是复制一个数据块,不检查其内容,也不在末尾附加一个空字符。

所以,当你这样做时:

double d;
...
fin >> d;

您将 double 存储到双变量中。但是……

如果你这样做:

double d;
...
fin.read((char*)&d, ...);

你告诉 c++:好的,这里 (&d) 我有一个地址,我希望你把它当作 char*(演员表)。并且该功能可以执行您想要执行的操作。但正如您在 doc 中看到的那样,该函数将在 &d 中放入一个 数据块,这与您期望的值无关。

这就是为什么operator>> 有效而read 无效的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多