简体   繁体   English

字符数组的整数转换

[英]Integer Conversion for Char Array

I've been trying to brush up on my C recently and was writing a program to manually parse through a PNG file. 我最近一直试图刷新我的C并编写一个程序来手动解析PNG文件。

I viewed the PNG file in a hex editor and noticed a stream of bytes that looked like 我在十六进制编辑器中查看了PNG文件,发现字节流看起来像

00 00 00 0D

in hex format. 十六进制格式。

This string supposedly represents a length that I am interested in. 该字符串应该代表我感兴趣的长度。

I used getc(file) to pull in the bytes of the PNG file. 我用getc(file)来拉入PNG文件的字节。

I created a char array as 我创建了一个char数组

char example[8];

to store the characters retrieved from getc . 存储从getc检索的字符。

Now, I have populated example and printing it with 现在,我已经填充了example并将其打印出来

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

shows 0, 0, 0, 0xd which is exactly what I want. 显示0, 0, 0, 0xd ,这正是我想要的。

However when I use 但是当我使用时

int x = atoi(example) 

or 要么

int x = strtol(example, NULL, 16)

I get back zero in both cases (I was expecting 13). 在这两种情况下,我都归零(本来是13)。 Am I missing something fundamental? 我错过了什么基本的东西?

atoi converts strings like "0" to its numeric equivalent, in this case 0 . atoi将字符串"0"转换为数字等价物,在本例中为0 What you have instead is the string "\\0\\0\\0\\0\\0\\0\\0\\r" which is nowhere near numeric characters. 你所拥有的是字符串"\\0\\0\\0\\0\\0\\0\\0\\r" ,它远不是数字字符。

If you want to interpret your bytes as a number you could do something like 如果您想将字节解释为数字,则可以执行以下操作

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

You will notice (in case you're using a x86 CPU) that you will get 218103808 instead of 13 due to little endianness: the farther you go right the more significant the number gets. 您会注意到(如果您使用的是x86 CPU),由于字节序少,您将得到218103808而不是13 :您走得越远,数字就越有意义。

As PNG uses big endian you can simply use be32toh (big endian to host endianess): 由于PNG使用big endian,因此您可以简单地使用be32toh (big endian来承载字节序):

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

atoi and strtol expect text strings, while you have an array of binary values. atoistrtol期望文本字符串,而你有一个二进制值数组。 To combine the individual bytes in an array to a larger integer, try something like: 要将数组中的各个字节组合为更大的整数,请尝试以下操作:

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

atoi etc. operates on (ascii) strings. atoi等对(ascii)字符串进行操作。
You would get 123 for "123", which is in bytes 49 50 41 0. 您将获得123的“ 123”,以字节49 50 41 0为单位。
What you have instead is binary 00 00 00 7B ... (well, endianess matters too). 相反,您拥有的是二进制00 00 00 7B ...(嗯,耐久性也很重要)。

Simple, but in this case wrong solution (ignoring endianess): 很简单,但是在这种情况下,错误的解决方案(忽略字节序):
Cast the array address to int* and then get a value with * . 将数组地址强制转换为int* ,然后使用*获得值。

As integers in PNG are supposed to be big endian in any case, 由于在任何情况下,PNG中的整数都应为大端字节,
the pointer casting would only work with big endian machines. 指针转换只适用于大端机器。
As portable solution, shifting the bytes with 24,16,8,0 and binary-or´ing them will do. 作为可移植的解决方案,将字节移位24、16、8、0并对其进行二进制或运算即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM