字符数组的整数转换

时间:2014-02-21 22:05:02

标签: c arrays type-conversion

我最近一直试图刷新我的C并正在编写一个程序来手动解析PNG文件。

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

的字节流
00 00 00 0D

以十六进制格式。

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

我使用getc(file)来拉入PNG文件的字节。

我创建了一个char数组

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)。我错过了一些基本的东西吗?

3 个答案:

答案 0 :(得分:4)

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(big endian来托管endianess):

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

答案 1 :(得分:2)

atoistrtol期望文本字符串,而您有一个二进制值数组。要将数组中的各个字节组合为更大的整数,请尝试类似:

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

答案 2 :(得分:1)

atoi等对(ascii)字符串进行操作 你会得到123为“123”,这是字节49 50 41 0 你所拥有的是二元00 00 00 7B ......(而且,结束也很重要)。

简单,但在这种情况下错误的解决方案(忽略endianess):
将数组地址转换为int*,然后使用*获取值。

由于PNG中的整数在任何情况下都应该是大端,因此 指针转换只适用于大端机器。
作为便携式解决方案,将字节移位24,16,8,0并将二进制或二进制转换它们。