在 C 中是否有一种简单的方法将数字转换为十六进制 ASCII 字符?
我正在为嵌入式设备编写 C 固件程序。我想通过串行端口发送一组十六进制字符值。有没有简单的方法将值转换为 ASCII 十六进制?
例如,如果数组包含 0xFF,我想发送 ASCII 字符串“FF”,或者对于十六进制值 0x3B,我想发送“3B”。
这通常是如何完成的?
我已经准备好串行发送函数,以便我可以执行此操作...
char msg[] = "Send this message";
SendString(msg);
并且 SendString 函数为传递的数组中的每个元素调用此函数:
// This function sends out a single character over the UART
int SendU( int c)
{
while(U1STAbits.UTXBF);
U1TXREG = c;
return c;
}
我正在寻找一个允许我执行此操作的函数...
char HexArray[5] = {0x4D, 0xFF, 0xE3, 0xAA, 0xC4};
SendHexArray(HexArray);
//Output "4D, FF, E3, AA, C4"
I am working a C firmware program for an embedded device. I want to send an array of hex char values over the serial port. Is there a simple way to convert a value to ASCII hex?
For example if the array contains 0xFF, I want to send out the ASCII string "FF", or for a hex value of 0x3B I want to send out "3B".
How is this typically done?
I already have the serial send functions in place so that I can do this...
char msg[] = "Send this message";
SendString(msg);
and the SendString function calls this function for each element in the passed array:
// This function sends out a single character over the UART
int SendU( int c)
{
while(U1STAbits.UTXBF);
U1TXREG = c;
return c;
}
I am looking for a function that will allow me to do this...
char HexArray[5] = {0x4D, 0xFF, 0xE3, 0xAA, 0xC4};
SendHexArray(HexArray);
//Output "4D, FF, E3, AA, C4"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您的编译器支持,您可以使用 itoa。否则,我会像 Nathan 的 & 中那样使用 sprintf 。马克的回答。如果支持 itoa 并且性能是一个问题,请尝试一些测试来确定哪个更快(过去的经验使我期望 itoa 更快,但是 YMMV)。
If your compiler supports it, you can use itoa. Otherwise, I'd use sprintf as in Nathan's & Mark's answers. If itoa is supported and performance is an issue, try some testing to determine which is faster (past experience leads me to expect itoa to be faster, but YMMV).
sprintf 会做到这一点。
sprintf(dest, "%X", src);
sprintf will do it.
sprintf (dest, "%X", src);
我将从数组查找开始。
然后简单地查找一下...
编辑
合并 Dysaster 的蚕食想法:
I'd start with an array lookup.
and then simply look it up ...
Edit
Incorporating Dysaster's nibbles idea:
汇编语言时代8位微机的经典技巧是将一个半字节的转换分成两段。 0到9的值和10到15的值。然后简单的算术保存了16字节的查找表。
一些旁注是有序的。首先,这是可行的,因为数字和字母在 ASCII 中都是连续的。如果您不幸需要EBCDIC,这仍然可以用作字母“A”到“ F' 在那里也是连续的(但字母表的其余部分被分成三个跨度)。
其次,我更改了
SendArray()
的签名。我的版本小心地使缓冲区无符号,当计划将字节提升为某种更大的整数类型以进行算术时,这通常更安全。如果它们已签名,则像nibble[(*msg)>>4]
这样的代码可能会尝试在数组中使用负索引,结果根本没有用处。最后,我添加了一个长度参数。对于一般的二进制转储,您可能没有任何有意义的字节值用作结束标记。为此,计数更为有效。
编辑:修复了一个错误:对于超过 10 的数字,算术是
c + 'A' - 10
,而不是c + 'A'
。感谢布鲁克斯·摩西抓住了这一点。The classic trick from the 8-bit micro in assembly language era is to break the conversion of a nybble into two segments. The value from 0 to 9 and the value from 10 to 15. Then simple arithmetic saves the 16-byte lookup table.
A couple of side notes are in order. First, this works because the digits and letters are each in contiguous spans in ASCII. If you are unfortunate enough to want EBCDIC, this still works as the letters 'A' through 'F' are contiguous there as well (but the rest of the alphabet is broken into three spans).
Second, I've changed the signature of
SendArray()
. My version is careful to make the buffer be unsigned, which is generally safer when planning to promote the bytes to some larger integral type to do arithmetic. If they are signed, then code likenibble[(*msg)>>4]
might try to use a negative index into the array and the result won't be at all useful.Finally, I added a length parameter. For a general binary dump, you probably don't have any byte value that makes sense to use as an end sentinel. For that, a count is much more effective.
Edit: Fixed a bug: for digits over 10, the arithmetic is
c + 'A' - 10
, notc + 'A'
. Thanks to Brooks Moses for catching that.使用
sprintf
将数字写入字符串,然后使用现有的SendString
函数通过 UART 发送该数字。当然,您可以一次执行一个数字:%02X
是一个 printf 系列函数的“nofollow noreferrer">格式化字符串,它表示用 0 填充元素直到宽度为 2,并将元素格式化为十六进制数字。02
部分确保当您想要打印0x0F
时,您会在输出中得到0F
而不仅仅是F
溪流。如果您使用小写的x
,您将得到小写字符(例如ff
而不是FF
)。Write the number to a string using
sprintf
and then use your existingSendString
function to send that over the UART. You can, of course, do this one number at a time:%02X
is a format string for theprintf
family of functions, it says pad the element with 0s until width 2 and format the element as a hexadecimal number.The
02
part ensures that when you want to print0x0F
that you get0F
instead of justF
in the output stream. If you use a lowercasex
you'll get lowercase characters (e.g.ff
instead ofFF
).