【问题标题】:Integer Conversion for Char Array字符数组的整数转换
【发布时间】:2014-03-23 15:48:06
【问题描述】:

我最近一直在努力复习我的 C 语言,并且正在编写一个程序来手动解析 PNG 文件。

我在十六进制编辑器中查看了 PNG 文件,发现一个字节流看起来像

00 00 00 0D

十六进制格式。

这个字符串应该代表我感兴趣的长度。

我使用getc(file) 来提取 PNG 文件的字节。

我创建了一个字符数组

char example[8];

存储从getc检索到的字符。

现在,我已经填充了 example 并使用

打印它
printf("%#x, %#x, %#x, %#x", example[0]....

显示 0, 0, 0, 0xd 这正是我想要的。

但是当我使用

int x = atoi(example) 

int x = strtol(example, NULL, 16)

在这两种情况下我都返回零(我期待 13)。我错过了一些基本的东西吗?

【问题讨论】:

    标签: c arrays type-conversion


    【解决方案1】:

    atoi 将类似"0" 的字符串转换为其等价的数字,在本例中为0。你所拥有的是字符串"\0\0\0\0\0\0\0\r",它与数字字符相去甚远。

    如果您想将字节解释为数字,您可以执行类似的操作

    char example[4] = {0, 0, 0, 0xd};
    printf("%d\n", *(uint32_t*) example);
    

    您会注意到(如果您使用的是 x86 CPU)您将获得218103808 而不是13 由于小端序:越远,数字越重要。

    作为PNG uses big endian,您可以简单地使用be32toh(大字节序来承载字节序):

    uint32_t* n = example;
    printf("%u\n", be32toh(*n)
    

    【讨论】:

    【解决方案2】:

    atoi 等对 (ascii) 字符串进行操作。
    “123”会得到 123,以字节 49 50 41 0 为单位。
    相反,您拥有的是二进制 00 00 00 7B ...(嗯,字节序也很重要)。

    简单,但在这种情况下是错误的解决方案(忽略字节序):
    将数组地址转换为int*,然后用*得到一个值。

    因为 PNG 中的整数在任何情况下都应该是大端,
    指针转换仅适用于大端机器。
    作为可移植的解决方案,用 24,16,8,0 移动字节并对它们进行二进制或运算即可。

    【讨论】:

    • 不要这样做,因为它具有硬件相关的结果。 PNG 规范应该说明它实际使用的字节顺序(假设它使用多个字节)。
    • 这就是我写“我不知道这个 PNG 数据是什么”的原因。同时查了一下:BE。正在编辑...
    【解决方案3】:

    atoistrtol 需要文本字符串,而您有一个二进制值数组。要将数组中的各个字节组合成一个更大的整数,请尝试以下操作:

    uint32_t x = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3];
    

    【讨论】:

      猜你喜欢
      • 2013-11-11
      • 1970-01-01
      • 1970-01-01
      • 2019-04-21
      相关资源
      最近更新 更多