将数据存入整数时会产生错误的数字?

时间:2013-01-23 05:29:32

标签: c parsing pointers buffer memcpy

我有一个像这样的字符缓冲区

char *buff = "aaaa0006france";

我想提取字节4到7并将其存储在int。

int i;
memcpy(&i, buff+4, 4);
printf("%d ", i);

但它打印垃圾值。

这有什么问题?

3 个答案:

答案 0 :(得分:5)

字符串

0006

没有与整数6相同的二进制表示。相反,它的位表示为四个ASCII字符,表示字形0,字形0,字形0,然后是字形6.这有十六进制表示

0x30303036

如果您尝试在little-endian系统上盲目地将这些位重新解释为数字,则返回808,464,438。在大端系统上,你会得到909,127,728。

如果要将字符串的子字符串转换为数字,则需要查找将字符串转换为数字的函数。您可能想尝试这样的事情:

char digits[5];

/* Copy over the digits in question. */
memcpy(digits, buff + 4, 4);
digits[4] = '\0';  /* Make sure it's null-terminated! */

/* Convert the string to a number. */
int i = strtol(digits + 4, NULL, 10);

这使用strtol函数将文本字符串转换为数字,以便将文本显式转换为整数。

希望这有帮助!

答案 1 :(得分:2)

在这里你需要记下两件事

  • 如何存储字符
  • 系统的结束

每个字符(Alphabhets,数字或特殊字符)都存储为7位ASCII值。在对一个4bytes int变量执行字符串(字符数组)“0006”的memcpy时,我们必须将字符串的地址作为源的地址和int的地址作为目标,如下所示。

char a[] = "0006";
int b = 0, c = 6;
memcpy(&b, a, 4);

a和b的值存储如下。

a 00110110 00110000 00110000 00110000
b 00000000 00000000 00000000 00000000
c 00000000 00000000 00000000 00000110
  MSB                             LSB

因为0字符的ASCII值为48且6字符为54.现在memcpy会尝试将a中的任何值复制到{{1} }。 b b的值将如下所示

memcpy

接下来是endianess。现在考虑我们正在以a 00110110 00110000 00110000 00110000 b 00110110 00110000 00110000 00110000 c 00000000 00000000 00000000 00000110 MSB LSB 之类的其他方式将值0006保留到字符缓冲区中,如果我们a[0] = 0; a[1] = 0; a[2]=0; a[3] = 6;,我们将获取值为100663296(memcpy )如果是小端机器,则不是6。在big endian机器中,您只能获得0x6000000的值。

6

因此,在编写将数字章程转换为整数值的函数时,我们需要考虑这两个问题。这些问题的简单解决方案是利用现有的系统api c 00000110 00000000 00000000 00000000 b 00000110 00000000 00000000 00000000 c 00000000 00000000 00000000 00000110 MSB LSB

答案 2 :(得分:1)

以下代码可能对您有帮助......

#include <stdio.h>

int main()
{
char *buff = "aaaa0006france";
char digits[5];

memcpy(digits, buff + 4, 4);
digits[4] = '\0';

int a = atoi(digits);
printf("int : %d", a);

return 0;
}