我想做什么:读取一系列4个字节,例如00000000 00000011 00000001 00000011
(这是一个随机的例子)来自二进制文件,并在程序中将其表示为整数。这样做的最佳方式是什么?
编辑解决方案 我忽略了PNG文件格式here的这部分规范,希望这对发现问题的任何人都有用。
我正在尝试使用PNG图像格式,但无法提取4字节数字。我已经成功打开并打印了文件的二进制表示,因此我知道我正在使用的数据没有损坏或格式错误。
我已经回顾了像Reading 16-bit integers from binary file c++这样的问题,以及32位等价物,但我无法辨别他们是否正在读取二进制文件中的整数,例如00000000 72 00000000
或读取整数字节,这就是我的目标。
例如,第一个块的前四个字节是00000000 00000000 00000000 00001101
或13
。
按照上述问题的例子,这应该== 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
任何见解都将受到赞赏
答案 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)