【问题标题】:How To Cast a 4-Bit Char Array to an Int?如何将 4 位字符数组转换为 Int?
【发布时间】:2018-09-02 15:53:14
【问题描述】:

我正在编写一个 C 程序来读取和解析 BMP 标头。前 2 个字符是字符,我打印得很好。但是,所有其他位都是小端格式的整数,所以我将它们向后存储。在十六进制中,我得到了正确的答案。但是,当我尝试将它们转换为 int(为了便于阅读)时,我得到一个无效的数字。

bmp.c --

printf("file size: "%02x %02x %02x %02x\n", bmp->size[0], bmp->size[1], bmp->size[2], bmp->size[3]);

printf("file size: "%d\n", bit2int(bmp->size));

bit2int 函数 --

int bit2int(void *thing)
{
    return *(int*)thing;
}

输出 --(实际文件大小为 415,798 字节)

file size: 00 06 58 36
file size: 911738368

edit 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);
}

【问题讨论】:

  • 0x065836 是大端的文件大小。只需使用移位和掩码解码值
  • 这似乎比 4 位值(范围:0-15)略大。
  • BMP 规范规定大小为小端。如果您执行了交换,那么您正在读取一个大端序号,如果您使用的是 intel,您将获得一个交换后的值。你能告诉我们你用来读取尺寸数据的代码吗?
  • @usr2564301 OP 可能意味着 4 个字节
  • @Jean-FrançoisFabre 当然!编辑历史记录

标签: c casting bitmap bit


【解决方案1】:

我喜欢 user1063935 的解决方案,但会使用移位运算符

int bit2int(unsigned char *thing)
{   
    return thing[3] + thing[2] << 8 + thing[1] << 16 + thing[0] << 24;
}

【讨论】:

    【解决方案2】:

    BMP 大小以小端序 为单位。所以你可能正在交换字节,从而得到一个大端整数,这是没有用的。

    那么你正在做的演员违反了严格的别名规则并且它是不可移植的。

    这是一小段代码,它试图尽可能地移植。它读取前 2 个标头字节,然后是 4 个 size 字节,并重建大小,假设值为 little endian:

    #include <stdio.h>
    #include <stdint.h>
    
    int main()
    {
       FILE *f = fopen("foo.bmp","rb");
       if (f)
      {
       unsigned char header[3] = {'\0'};
       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 %lu\n",header,(unsigned long)size);
       fclose(f);
       }
    
    }
    
    • 代码可以毫无问题地在大端架构上编译
    • 文件以二进制形式打开,因此可以在 Windows 和 Linux 上运行
    • 为简单起见,我在阅读标题时省略了大小检查。它可以很容易地添加。

    【讨论】:

    • 这绝对是正确的做法!应该将数据读入unsigned char 缓冲区,并以这种方式使用缓冲区内容来构造实际的标头字段。不过,我会使用辅助函数(每种类型一个)。特别是,包含 BMP 文件描述的内存中struct bmp_file 或类似文件不需要与文件具有相同的类型和字段顺序。试图构造一个可以直接从文件中fread()struct,是非常不可移植且容易损坏的。
    【解决方案3】:

    也许

    int bit2int(unsigned char *thing)
    {
        return thing[3] + 256*thing[2] + 65536*thing[1] + 16777216*thing[0];
    }
    

    【讨论】:

    • 这行得通,在这个类的上下文中位移位会更好。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2017-01-18
    • 1970-01-01
    • 2013-04-03
    • 2014-10-30
    • 2011-04-16
    • 1970-01-01
    • 2021-12-21
    • 2016-08-14
    相关资源
    最近更新 更多