如何将字符串中的十六进制值转换为实际字节
How to convert hex values inside a string into a actual byte
我需要将“FAFBFCFD”等字符串中包含的十六进制转换为数组或 uint32。
我试过这样的 sscanf:
uint8_t ns[4];
sscanf("FAFBFCFD", "%X%X%X%X", &ns[0], &ns[1], &ns[2], &ns[3]);
但我在数组中得到的只是 ff ff ff 7f
编辑:
就像@Clifford 所说的那样,在这种情况下 sscanf 返回的值是一个 int,如果您将指针传递给 uint8_t,程序将会崩溃。
启用编译器警告,您会发现它们在这种情况下非常有用。当我在 x64 GCC 11.1 上启用 -Wall -Wextra -pedantic-errors
时,我收到此警告:
<source>:9:26: warning: format '%X' expects argument of type 'unsigned int *', but argument 3 has type 'uint8_t *' {aka 'unsigned char *'} [-Wformat=]
9 | sscanf("FAFBFCFD", "%X%X%X%X", &ns[0], &ns[1], &ns[2], &ns[3]);
| ~^ ~~~~~~
| | |
| | uint8_t * {aka unsigned char *}
| unsigned int *
| %hhX
这使问题变得非常清楚。 %X
仅适用于 unsigned int *
,但您的参数类型为 uint8_t *
(也称为 unsigned char *
)。结果是未定义的行为。该警告还告诉您改用 %hhx
,但您还必须指定您只想为每个参数读取两个字符。因此,您对 sscanf
的调用应如下所示:
sscanf("FAFBFCFD", "%2hhx%2hhx%2hhx%2hhx", &ns[0], &ns[1], &ns[2], &ns[3]);
此外,inttypes.h
中定义了一些宏,它们扩展为 uintX_t
/intX_t
类型的正确格式说明符,等等。所以你可以使用 SCNx8
宏,它保证是 uint8_t
的正确格式,而不是 hhx
:
sscanf("FAFBFCFD",
"%2"SCNx8"%2"SCNx8"%2"SCNx8"%2"SCNx8"",
&ns[0], &ns[1], &ns[2], &ns[3]);
虽然它确实让事情看起来有点丑...
我需要将“FAFBFCFD”等字符串中包含的十六进制转换为数组或 uint32。
我试过这样的 sscanf:
uint8_t ns[4];
sscanf("FAFBFCFD", "%X%X%X%X", &ns[0], &ns[1], &ns[2], &ns[3]);
但我在数组中得到的只是 ff ff ff 7f
编辑:
就像@Clifford 所说的那样,在这种情况下 sscanf 返回的值是一个 int,如果您将指针传递给 uint8_t,程序将会崩溃。
启用编译器警告,您会发现它们在这种情况下非常有用。当我在 x64 GCC 11.1 上启用 -Wall -Wextra -pedantic-errors
时,我收到此警告:
<source>:9:26: warning: format '%X' expects argument of type 'unsigned int *', but argument 3 has type 'uint8_t *' {aka 'unsigned char *'} [-Wformat=]
9 | sscanf("FAFBFCFD", "%X%X%X%X", &ns[0], &ns[1], &ns[2], &ns[3]);
| ~^ ~~~~~~
| | |
| | uint8_t * {aka unsigned char *}
| unsigned int *
| %hhX
这使问题变得非常清楚。 %X
仅适用于 unsigned int *
,但您的参数类型为 uint8_t *
(也称为 unsigned char *
)。结果是未定义的行为。该警告还告诉您改用 %hhx
,但您还必须指定您只想为每个参数读取两个字符。因此,您对 sscanf
的调用应如下所示:
sscanf("FAFBFCFD", "%2hhx%2hhx%2hhx%2hhx", &ns[0], &ns[1], &ns[2], &ns[3]);
此外,inttypes.h
中定义了一些宏,它们扩展为 uintX_t
/intX_t
类型的正确格式说明符,等等。所以你可以使用 SCNx8
宏,它保证是 uint8_t
的正确格式,而不是 hhx
:
sscanf("FAFBFCFD",
"%2"SCNx8"%2"SCNx8"%2"SCNx8"%2"SCNx8"",
&ns[0], &ns[1], &ns[2], &ns[3]);
虽然它确实让事情看起来有点丑...