我有一个像这样的字符缓冲区
char *buff = "aaaa0006france";
我想提取字节4到7并将其存储在int。
中int i;
memcpy(&i, buff+4, 4);
printf("%d ", i);
但它打印垃圾值。
这有什么问题?
答案 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;
}