二进制文件

时间:2015-11-03 23:57:33

标签: c++ file-io binary

我想做什么:读取一系列4个字节,例如00000000 00000011 00000001 00000011(这是一个随机的例子)来自二进制文件,并在程序中将其表示为整数。这样做的最佳方式是什么?

编辑解决方案 我忽略了PNG文件格式here的这部分规范,希望这对发现问题的任何人都有用。

我正在尝试使用PNG图像格式,但无法提取4字节数字。我已经成功打开并打印了文件的二进制表示,因此我知道我正在使用的数据没有损坏或格式错误。

我已经回顾了像Reading 16-bit integers from binary file c++这样的问题,以及32位等价物,但我无法辨别他们是否正在读取二进制文件中的整数,例如00000000 72 00000000或读取整数字节,这就是我的目标。

例如,第一个块的前四个字节是00000000 00000000 00000000 0000110113

按照上述问题的例子,这应该== 13:

int test;
img.read( (char*) &test, sizeof(test));

然后输出218103808

我还尝试了使用带有字符数组和整数数据成员的联合的方法,并得到218103808的相同输出

另外,在我的系统sizeof(int)上等于4

最后,为了确保它不是一个格式错误的PNG(我不是很确定)我使用gimp导入它然后将其导出为新文件,因此本机创建在我的系统上。

修改

正如我所提到的,在seekg(8)之后,接下来的四个字节是00000000 00000000 00000000 00001101,但当我决定使用

测试read函数时
bitset<32> num;
img.read( (char*) &num, sizeof(int) );

输出00001101 00000000 00000000 00000000 在这里,我只是对这一部分感到困惑。就好像这里的字节相反。这个字节串等于218103808

任何见解都将受到赞赏

1 个答案:

答案 0 :(得分:3)

请注意,218103808是十六进制的0x0D000000。您可能想了解Endianess

这意味着您正在阅读的数据采用大端格式,而您的平台使用的是小端。

基本上你需要反转4个字节,(你可能想要使用无符号整数),所以你得到0x0000000D,(13十进制),你可以这样做:

#define BSWAPUINT(x)  ((((x) & 0x000000ff) << 24) |\
                       (((x) & 0x0000ff00) << 8)  |\
                       (((x) & 0x00ff0000) >> 8)  |\
                       (((x) & 0xff000000) >> 24))
unsigned int test;
img.read( (char*) &test, sizeof(test));
test = BSWAPUINT(test);

上述代码仅在代码在小端平台上运行时才有效。

要让您的代码独立于您的平台是大端还是小端,您可以自己将字节汇编为整数,假设您知道数据格式是大端,您可以这样做:

unsigned char buf[4];
unsigned int test;
img.read( (char*) &test, sizeof(test));
test  = (unsigned int)buf[0] << 24;
test |= buf[1] << 16;
test |= buf[2] << 8;
test |= buf[3];

或者,在unix系统上,您可以#include <arpa/inet.h>并使用ntohl()

test = ntohl(test);

(以这种方式处理数据,你也可以更好地使用类型,例如uint32_t而不是int / unsigned int&#39; s,来自stdint.h