在C++中从二进制文件中读取32位整数?

21

我的二进制文件看起来像这样。

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 等类型。但是都失败了。

为什么这些方法都不起作用?我应该怎么做才能达到目标呢?


3
你有没有检查文件是否成功打开?读取后流的状态如何?(失败或坏状态?) - Daniel Jour
2
请记住打开模式 - 打开的第二个参数 (http://en.cppreference.com/w/cpp/io/ios_base/openmode)。 - Hcorg
2
你需要知道在保存文件时使用了哪种字节序。小端序(例如Intel x86):最不重要的字节位于最低地址,大端序(例如互联网):最重要的字节位于最低地址。 - Erik Alapää
如果您正在从LeCun上的Intel PC读取MNIST图像数据集,则需要像@ErikAlapää提到的那样反转字节顺序。 - DavidJ
2
@plhn 只是一点小建议:也许 if 不是你的 ifstream 变量的有效名称... - Alessandro Jacopson
2个回答

35
您有两个问题:
  1. 确保您从流中读取您打算读取的字节(没有更少,也没有更多)。

    我建议使用以下语法:

    uint32_t a;

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

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

    问:如果您在 PC 上,则您的 CPU 可能是 小端模式。您知道您的数据流是否也是小端模式,还是大端模式吗?

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

此外:

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


实际上,有三个问题:他还需要读取十六进制数据,这可能是最大的问题。 - Mark Jansen
最好解释一些关于第一个问题的原因。(=为什么您建议使用“read”函数,而不是输入流?) - plhn
5
为什么 >> 不起作用?这是一种文档化的行为吗? - zhangxaochen
1
@zhangxaochen正在寻找数字的ASCII表示,为了读取42,它期望在流中看到0x34、0x32,而不是0x2a代表'4'和'2'。 - pm100

5

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

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

1
错误:无法使用类型为'int32_t *'(又名'int *')的rvalue初始化类型为'char_type *'(又名'char *')的参数。这是怎么回事? - LRDPRDX
@LRDPRDX,“what”是什么情况?你是否提出了问题并提供了示例?(在我的片段中,没有转换为char,也没有初始化)。 - VolAnd
2
我刚刚尝试编译你的片段,但是出现了我上面打印的错误。 - LRDPRDX
@LRDPRDX 我没有机会检查(Galaxy Note-3上没有C++编译器)...但这肯定是指针类型转换的问题。尝试为&a添加显式转换:file.read((char*)&a, sizeof(a)); - VolAnd
2
我暗示了它。 - LRDPRDX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接