【问题标题】:Read 32-bit integer from binary file in C++?从 C++ 中的二进制文件中读取 32 位整数?
【发布时间】:2015-11-11 00:19:06
【问题描述】:

我的二进制文件如下所示。

00000000: 0000 0803 0000 ea60 0000 001c 0000 001c
00000010: 0000 0000 0000 0000 0000 0000 0000 0000

左栏是地址。

我刚刚尝试阅读0000 0803(=2051)如下

ifstream if;
if.open("file");
uint32_t a;
if >> a;

正如预期的那样......它不起作用:-(
a 在执行后只是 0。
我试过long, int, unsigned int, unsigned long。都失败了。

为什么这些不起作用,我该如何实现目标?

【问题讨论】:

  • 您检查文件是否打开正确?读取后流的状态是什么? (失败还是坏状态?)
  • 记住打开模式 - 打开的第二个参数 (en.cppreference.com/w/cpp/io/ios_base/openmode)。
  • 并且您需要知道保存文件时使用的字节顺序。 Little-endian(例如 Intel x86):最低地址上的最低有效字节,Big-endian(例如互联网):最低地址上的最高有效字节。
  • 如果您在 Intel PC 上从 LeCun 读取 MNIST 图像数据集,那么您需要反转字节顺序,如 @ErikAlapää 所述。
  • @plhn 只是一个旁注:也许if 不是您的ifstream 变量的有效名称...

标签: c++ file fstream


【解决方案1】:

你有两个问题:

  1. 确保您从流中读取您想要的字节(不多也不少)。

    我推荐这种语法:

    uint32_t a;

    inFILE.read(reinterpret_cast<char *>(&a), sizeof(a));

  2. 确保您以正确的字节顺序解释这些字节。

    问:如果你在 PC 上,你的 CPU 可能是little endian。你知道你的数据流是小端还是大端?

    如果数据是大端的,我会考虑使用标准网络函数来适应字节顺序:ntohl() 等:http://www.retran.com/beej/htonsman.html

还有:

遵循 Hcorg 和 Daniel Jour 的建议:不要忘记“打开模式”参数,也不要忘记检查“文件打开”错误。

【讨论】:

  • 其实有3个问题:他还要读取16进制的数据,这可能是最大的问题。
  • 关于第一个问题最好解释一些原因。(=为什么你推荐read函数,而不是输入流?)
  • 为什么>> 不起作用?这是记录在案的行为吗?
  • @zhangxaochen >> 正在寻找数字的 ASCII 表示,读取 42 它期望在流 '4' 和 '2' 中看到 0x34、0x32,而不是 0x2a
【解决方案2】:

以二进制模式打开文件,然后使用read()方法,类似:

uint32_t a;
ifstream file ("file", ios::in | ios::binary);
if (file.is_open())
{
     file.read ((char*)&a, sizeof(a));
}

【讨论】:

  • 错误:无法使用“int32_t *”(又名“int *”)类型的右值初始化“char_type *”(又名“char *”)类型的参数。怎么样?
  • @LRDPRDX “什么”呢?你有没有就你的案例提出问题并提供一个例子? (在我的 sn-p 中没有转换为 char,也没有初始化)。
  • 我只是想编译你的sn-p。还有我上面打印的错误。
  • @LRDPRDX 我没有机会检查(在 Galaxy Note-3 中没有适用于 Android 的 c++ 编译器)......但这绝对是指针类型转换的问题。尝试为&a 添加显式转换:file.read((char*)&a, sizeof(a));
  • 含蓄地我在说它。
猜你喜欢
  • 2012-10-12
  • 2011-06-12
  • 2011-09-25
  • 2021-09-07
  • 2016-11-13
  • 1970-01-01
  • 2015-04-27
  • 1970-01-01
  • 2015-07-30
相关资源
最近更新 更多