我正在编码一个C程序以读取和解析BMP标头。前两个字符是字符,我打印正常。但是,所有其他位均以小endian格式为int,所以我将它们向后存储。在十六进制中,我得到了正确的答案。但是,当我尝试将它们投射到INT(以获取可读性(时,我会得到一个无效的数字。
bmp.c-
printf("file size: "%02x %02x %02x %02xn", bmp->size[0], bmp->size[1], bmp->size[2], bmp->size[3]);
printf("file size: "%dn", bit2int(bmp->size));
bit2int函数 -
int bit2int(void *thing)
{
return *(int*)thing;
}
输出 - (实际文件大小为415,798字节(
file size: 00 06 58 36
file size: 911738368
编辑1-我当前正在使用
的功能void storebackwards(void *dst, void *src, int offset, int n) {
for(int i = n; i > 0; i--)
memcpy( dst + n - i, src + offset + i - 1, 1);
}
我喜欢User1063935'解决方案,但会使用Shift Operator
int bit2int(unsigned char *thing)
{
return thing[3] + thing[2] << 8 + thing[1] << 16 + thing[0] << 24;
}
也许
int bit2int(unsigned char *thing)
{
return thing[3] + 256*thing[2] + 65536*thing[1] + 16777216*thing[0];
}
bmp大小在 little endian 中。因此,您可能会交换字节,因此获得了一个很大的endian整数,这是没有用的。
然后,您要做的演员违反严格的别名规则和这不是便携式的。
这是一小部分代码,试图尽可能便携。它读取前2个标题字节,然后读取4个大小字节,并重建大小,假设值是小endian:
#include <stdio.h>
#include <stdint.h>
int main()
{
FILE *f = fopen("foo.bmp","rb");
if (f)
{
unsigned char header[3] = {' '};
unsigned char size_buffer[4];
int nb_read = fread(header,2,1,f);
nb_read = fread(size_buffer,4,1,f);
uint32_t size = size_buffer[0] + (size_buffer[1]<<8) +
(size_buffer[2]<<16) + (size_buffer[3]<<24);
printf("header: %s, size %lun",header,(unsigned long)size);
fclose(f);
}
}
- 该代码可以在没有问题的情况下编译在大的endian架构上
- 该文件以二进制打开,因此在Windows&amp;Linux
- 我在阅读标头时省略了尺寸检查,以简单起见。它可以很容易地添加。