我尝试在不使用任何外部库的情况下,将uint16_t
值转换为C中字符串的十六进制表示。到目前为止,我已经使用this答案实现了可靠的转换。然而,我的用例要求,如果uint16_t
值小于0x1000
,则结果输出需要用前导零填充。例如,如果我像这样调用函数:
char s[5];
itohexa(s, 1230); //(1230->0x04CE)
字符串
我会得到:
04CE
型
然而,这个函数给了我这个:
4CE
型
在字符串中表示的uint16_t中的实际字节数对我的用例很重要。我希望值偶尔会超过0x0FFF
,所以只是在任何uint16_t
数字中添加一个前导零字符(到目前为止,我一直在做的工作)是不够的。
我是这么做的:
static char *itohexa_helper(char *dest, uint16_t x, uint8_t pad) {
if (x >= 16 || pad) {
dest = itohexa_helper(dest, x/16, pad);
pad = 1;
}
*dest++ = "0123456789ABCDEF"[x & 15];
return dest;
}
char *itohexa(char *dest, uint16_t x) {
uint8_t padding = (x < 0x1000);
*itohexa_helper(dest, x, padding) = '\0';
return dest;
}
型
在这种情况下,即使值的前4个最高有效位为零,padding
和pad
也不会进行转换吗?只是为了记录:对上述代码所做的修改仍然会产生与上面链接的answer中提到的原始结果相同的结果。
3条答案
按热度按时间4dbbbstv1#
有时候,使用(更复杂的)递归来解决问题比使用迭代更有趣。你的代码很接近了!
你想要的不是“填充”,而是前导的“0”。设置、清除填充标志可能会起作用(如果正确完成),但只能给你给予一个前导零。
下面是你重新编写的代码:
字符串
输出量:
型
注意没有任何base 10常量.
编辑
如果你100%确定(即0x0064%)你想要4个十六进制数字作为C字符串,那么有这样的:(它比我的竞争对手在这个友好的竞争中的代码短1条指令...:-)
型
你可能需要使用数组索引,这取决于MCU的大/小端。多有趣啊!!
webghufk2#
一个简单的非递归方法:从最低有效位到最高有效位构建字符串。
字符串
apeeds0o3#
我可能会尽可能明确地写出来,就像这样(在评论中解释):
字符串
测试用例:
型
输出
ZERO_PAD false
:型
输出
ZERO_PAD true
:型
ZERO_PAD
可以自然地作为一个参数,或者你可以创建两个不同的函数,等等。