先抛出两种十六进制数据转字符串的方法
方法一:
// 十六进制数字转字符串,如: 0xf1---> "f1"
static void Val2Hex(int8_t* hex, uint8_t val){
static const char* hexTable="0123456789ABCDEF";
*hex = hexTable[val>>4]; // 取高4位,再下标寻址
*(hex+1) = hexTable[val&0xf]; // 取低4位,再下标寻址
}
此方法主要是利用字符替换的方法来实现转换,为什么这种方法性能比sprintf还高了,主要是利用了数字下标的方法来实现,虽说是一个一个的替换,但是省去了调用系统库调用以及数值转换,因此性能较高。
附带一个十六进制字符串转回十六进制数值的方法,字符串转数字 如: "f1"---> 0xf1
static uint8_t Hex2Val(int8_t* hex){
if(*hex>='0'&&*hex<='9')
return *hex-'0';
if(*hex>='A' && *hex<='F')
return *hex-'A'+10;
if(*hex>='a'&&*hex<='f')
return *hex-'a'+10;
throw -EINVAL;
}
方法二
char a=0xf1;
char buff[3]={0};// 长度必须最好比转换后的字符串长度大1,且赋值为'\0',否则容易出现数组访问越界
sprintf(buff,"%02x", (unsigned char)a); //此处必须强转为无符号字符,由于0xf1是f开头,被当成负数,如果不强转会将0xf1当成0xfffffff1来处理,所得的结果就是"fffffff1"。
std::cout << buff << std::endl;
结果是:
"f1"
如上所述,如果我们在sprintf当中不遇到‘f’开头的hex时,得到的结果就不是我们想要的,这是为什么了?
主要是因为“%x”所需要的参数为integer型。
大家都知道,负数高位是1,如果拓展成更长的字节,自然会补1,因此oxf1会先转成oxfffffff1,在进行sprintf的格式化输入,所以得到结果就成了
0xfffffff1