2015-11-03 106 views
2

整数我想要做的:读了一系列的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

任何有识之士将不胜感激

+0

有关如何开始的一般概念,您可能需要查看一下我的旧答案。 http://stackoverflow.com/a/5762648/179910 –

+0

谢谢,这是相当有帮助的。我对于为什么得到我编辑中提到的值“218103808”有点遗憾。我在你的头文件验证功能中看到它。我知道它表示的是13的长度,但它为什么会损坏到另一个数字?再次感谢 –

+0

我想你对小端符号感到困惑。 https://en.wikipedia.org/wiki/Endianness的第一段应该让你走上正轨。 –

回答

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类型的,从stdint.h

+0

这当然是这种情况。当我研究文件格式时,我无法相信我忽视了PNG的排序。万分感谢 –