c - sscanf() 将十六进制整数转换为整数数组与无符号字符

标签 c types scanf strtol

我正在将 MAC 地址的字符串表示形式转换为 UINT8 的数组s 定义为 unsigned char 。我很好奇为什么sscanf()当我读入 UINT8 数组时,将读取全 0当我读入常规 32 位数组 int 时,s 和实际值s。它几乎就像是砍掉了 int 错误端的 8 位。

char *strMAC = "11:22:33:AA:BB:CC";

typedef unsigned char UINT8;
UINT8 uMAC[6];

int iMAC[6];

sscanf( (const char*) strMac, 
        "%x:%x:%x:%x:%x:%x", 
        &uMAC[0], &uMAC[1], &uMAC[2], &uMAC[3], &uMAC[4], &uMAC[5] );
printf( "%x:%x:%x:%x:%x:%x", 
        uMAC[0], uMAC[1], uMAC[2], uMAC[3], uMAC[4], uMAC[5] );
// output: 0:0:0:0:0:0

sscanf( (const char*) strMac, 
        "%x:%x:%x:%x:%x:%x", 
        &iMAC[0], &iMAC[1], &iMAC[2], &iMAC[3], &iMAC[4], &iMAC[5] );
printf( "%x:%x:%x:%x:%x:%x", 
        iMAC[0], iMAC[1], iMAC[2], iMAC[3], iMAC[4], iMAC[5] );
// output: 11:22:33:AA:BB:CC

更新:%hhx适用于 C99 及更高版本,但我有一个旧的代码库,所以我最终选择 strtoul() :

char *str = strMac;
int i = 0;
for(i = 0; i < 6; i++, str+=3) {
    uMAC[i] = strtoul(str, NULL, 16);
}

最佳答案

TL;DR - 由于参数类型不匹配,第一个片段 invkoes UB。


为了详细说明,引用 %x 格式说明符的参数类型要求,来自 C11 标准,第 §7.21.6.2 章,fscanf() 函数,(强调我的)

x Matches an optionally signed hexadecimal integer, whose format is the same as expected for the subject sequence of the strtoul() function with the value 16 for the base argument. The corresponding argument shall be a pointer to unsigned integer.

所以,在使用时

 sscanf( (const char*) strMac, 
    "%x:%x:%x:%x:%x:%x", 
    &uMAC[0], &uMAC[1], &uMAC[2], &uMAC[3], &uMAC[4], &uMAC[5] );

在您的代码中,您为 %x 提供了错误类型的参数。再次按照标准,

[...]. Unless assignment suppression was indicated by a *, the result of the conversion is placed in the object pointed to by the first argument following the format argument that has not already received a conversion result. If this object does not have an appropriate type, or if the result of the conversion cannot be represented in the object, the behavior is undefined.

因此,提供错误的类型作为参数正在调用 undefined behaviour .


解决方案:

要指示您要提供(有符号或无符号)char 类型参数,您需要使用以 hh 长度修饰符为前缀的格式说明符,就像 %hhxscanf() 系列一样。

关于c - sscanf() 将十六进制整数转换为整数数组与无符号字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31814956/

相关文章:

C++ Windows 移除最大化框

c - strncpy 在不同 IDE 中的行为

c - C中的多维数组数据类型

c - 如何通过C中的头文件使函数可见

C++:char** 到 const char** 的转换

c++ - 在 C++ 中获取 double 的精确位表示

typescript - TS2339 : Property does not exist on union type - property string | undefined

c - 为什么在使用 Win32 ConsoleInput 函数时 scanf 不起作用?

c - 不知道如何修复错误

c - 从 fscanf 接收到奇怪的数字 - int 转换?