sscanf 1字节十六进制数据,没有溢出

GPT*_*nno 6 c embedded scanf overflow

我需要扫描6字节数据的十六进制表示并将其存储在一个6字节的数组中.

请注意我在嵌入式系统中,所以每个字节数.

以这种方式使用sscanf:

uint8_t buf[6];
char hex[13] = "123456789ABC";
sscanf(hex, "%02X%02X%02X%02X%02X%02X", &buf[0], &buf[1], &buf[2], &buf[3], &buf[4], &buf[5]);
Run Code Online (Sandbox Code Playgroud)

溢出因为每个%02X说明符都在uint32_t中加载.

  • %02lX将加载到uint32_t中
  • %02hX将加载到uint16_t中

是否有一个在uint8_t中加载的说明符?(我在任何地方都找不到)

还有另一种方法吗?

我试着这样做:

sscanf(hex, "%08lX%04hX", &buf[0], &buf[4]);
Run Code Online (Sandbox Code Playgroud)

这不会溢出,但由于我在小端结构上,订单混淆了......

Cli*_*ord 9

请注意我在嵌入式系统中,所以每个字节数.

如果是这样的话那么sscanf可能是不明智的; 它的堆栈使用和代码空间将使您在使用尽可能小的数据类型时可能感知到的任何保存相形见绌.考虑:

uint8_t hexdigit( char hex )
{
    return (hex <= '9') ? hex - '0' : 
                          toupper(hex) - 'A' + 10 ;
}

uint8_t hexbyte( const char* hex )
{
    return (hexdigit(*hex) << 4) | hexdigit(*(hex+1)) ;
}
Run Code Online (Sandbox Code Playgroud)

然后你的代码变成:

char hex[13] = "123456789ABC";

for( int b = 0; b < 6; b++ )
{
    buf[b] = hexbyte( &hex[b * 2] ) ;
}
Run Code Online (Sandbox Code Playgroud)

如果必须使用sscanf()但是您的库不支持hh格式说明符限定符(因为许多嵌入式或旧的C库可能不支持),那么您可以使用中间整数:

char hex[13] = "123456789ABC";

for( int b = 0; b < 6; b++ )
{
    unsigned byte ;

    sscanf( &hex[b * 2], "%02X", byte ) ;
    buf[b] = (unit8_t)byte ;
}
Run Code Online (Sandbox Code Playgroud)


dho*_*dho 8

您想要%02hhX在unsigned char数组上使用.(好吧uint8_t)