强悍的书签 · 总结历史面向未来——读《中华羌族历史文化集成 ...· 1 月前 · |
帅气的红酒 · Orpheus and Eurydice ...· 1 月前 · |
爱笑的肉夹馍 · 古龙武侠小说书籍全套全集72册1-2辑一二辑 ...· 2 月前 · |
刚失恋的拐杖 · 記憶の場| 絨花| ...· 9 月前 · |
茫然的黑框眼镜 · 实用大师app安卓手机版下载-实用大师app ...· 1 年前 · |
我有:
uint8 buf[] = {0, 1, 10, 11};
我希望将字节数组转换为字符串,以便可以使用printf打印该字符串:
printf("%s\n", str);
和get (冒号不是必需的):
"00:01:0A:0B"
任何帮助都将不胜感激。
发布于 2011-06-15 19:33:00
printf("%02X:%02X:%02X:%02X", buf[0], buf[1], buf[2], buf[3]);
有关更通用的方法:
int i;
for (i = 0; i < x; i++)
if (i > 0) printf(":");
printf("%02X", buf[i]);
printf("\n");
要连接字符串,有几种方法可以做到这一点。我可能会保留一个指向字符串末尾的指针,并使用sprintf。您还应该跟踪数组的大小,以确保它不会超过分配的空间:
int i;
char* buf2 = stringbuf;
char* endofbuf = stringbuf + sizeof(stringbuf);
for (i = 0; i < x; i++)
/* i use 5 here since we are going to add at most
3 chars, need a space for the end '\n' and need
a null terminator */
if (buf2 + 5 < endofbuf)
if (i > 0)
buf2 += sprintf(buf2, ":");
buf2 += sprintf(buf2, "%02X", buf[i]);
buf2 += sprintf(buf2, "\n");
发布于 2012-10-11 20:46:09
对于completude,您也可以轻松地完成,而无需调用任何繁重的库函数(没有snprintf、strcat,甚至是memcpy)。例如,如果您正在编写一些微控制器或操作系统内核,而libc不可用,那么它可能会很有用。
如果你在谷歌上搜索,你能在周围找到类似的代码,没有什么特别的。实际上,它并不比调用snprintf复杂多少,而且速度也快得多。
#include <stdio.h>
int main(){
unsigned char buf[] = {0, 1, 10, 11};
/* target buffer should be large enough */
char str[12];
unsigned char * pin = buf;
const char * hex = "0123456789ABCDEF";
char * pout = str;
int i = 0;
for(; i < sizeof(buf)-1; ++i){
*pout++ = hex[(*pin>>4)&0xF];
*pout++ = hex[(*pin++)&0xF];
*pout++ = ':';
*pout++ = hex[(*pin>>4)&0xF];
*pout++ = hex[(*pin)&0xF];
*pout = 0;
printf("%s\n", str);
}
这是另一个略短的版本。它只是避免了中间索引变量i和重复最后一个大小写代码(但终止字符被写了两次)。
#include <stdio.h>
int main(){
unsigned char buf[] = {0, 1, 10, 11};
/* target buffer should be large enough */
char str[12];
unsigned char * pin = buf;
const char * hex = "0123456789ABCDEF";
char * pout = str;
for(; pin < buf+sizeof(buf); pout+=3, pin++){
pout[0] = hex[(*pin>>4) & 0xF];
pout[1] = hex[ *pin & 0xF];
pout[2] = ':';
pout[-1] = 0;
printf("%s\n", str);
}
下面是另一个版本来回答一个评论,说我使用了一个“技巧”来知道输入缓冲区的大小。实际上,这不是一种技巧,而是一种必要的输入知识(您需要知道要转换的数据的大小)。我通过将转换代码提取到一个单独的函数中,使这一点变得更加清晰。我还为目标缓冲区添加了边界检查代码,如果我们知道我们在做什么,那么这并不是真正必要的。
#include <stdio.h>
void tohex(unsigned char * in, size_t insz, char * out, size_t outsz)
unsigned char * pin = in;
const char * hex = "0123456789ABCDEF";
char * pout = out;
for(; pin < in+insz; pout +=3, pin++){
pout[0] = hex[(*pin>>4) & 0xF];
pout[1] = hex[ *pin & 0xF];
pout[2] = ':';
if (pout + 3 - out > outsz){
/* Better to truncate output string than overflow buffer */
/* it would be still better to either return a status */
/* or ensure the target buffer is large enough and it never happen */
break;
pout[-1] = 0;
int main(){
enum {insz = 4, outsz = 3*insz};
unsigned char buf[] = {0, 1, 10, 11};
char str[outsz];
tohex(buf, insz, str, outsz);
printf("%s\n", str);
}
发布于 2016-12-16 04:59:17
上面已经存在类似的答案,我添加了这个答案来解释下面这行代码是如何工作的:
ptr += sprintf(ptr, "%02X", buf[i])
这很复杂,也不容易理解,我在下面的评论中做了解释:
uint8 buf[] = {0, 1, 10, 11};
/* Allocate twice the number of bytes in the "buf" array because each byte would
* be converted to two hex characters, also add an extra space for the terminating
* null byte.
* [size] is the size of the buf array */
char output[(size * 2) + 1];
/* pointer to the first item (0 index) of the output array */
char *ptr = &output[0];
int i;
for (i = 0; i < size; i++) {
/* "sprintf" converts each byte in the "buf" array into a 2 hex string
* characters appended with a null byte, for example 10 => "0A\0".
* This string would then be added to the output array starting from the
* position pointed at by "ptr". For example if "ptr" is pointing at the 0
* index then "0A\0" would be written as output[0] = '0', output[1] = 'A' and
* output[2] = '\0'.
* "sprintf" returns the number of chars in its output excluding the null
* byte, in our case this would be 2. So we move the "ptr" location two
* steps ahead so that the next hex string would be written at the new
* location, overriding the null byte from the previous hex string.