首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在C中将字节数组转换为十六进制字符串?

如何在C中将字节数组转换为十六进制字符串?
EN

Stack Overflow用户
提问于 2011-06-15 19:30:25
回答 16查看 266.2K关注 0票数 97

我有:

代码语言:javascript
复制
uint8 buf[] = {0, 1, 10, 11};

我希望将字节数组转换为字符串,以便可以使用printf打印该字符串:

代码语言:javascript
复制
printf("%s\n", str);

和get (冒号不是必需的):

代码语言:javascript
复制
"00:01:0A:0B"

任何帮助都将不胜感激。

EN

回答 16

Stack Overflow用户

回答已采纳

发布于 2011-06-15 19:33:00

代码语言:javascript
复制
printf("%02X:%02X:%02X:%02X", buf[0], buf[1], buf[2], buf[3]);

有关更通用的方法:

代码语言:javascript
复制
int i;
for (i = 0; i < x; i++)
{
    if (i > 0) printf(":");
    printf("%02X", buf[i]);
}
printf("\n");

要连接字符串,有几种方法可以做到这一点。我可能会保留一个指向字符串末尾的指针,并使用sprintf。您还应该跟踪数组的大小,以确保它不会超过分配的空间:

代码语言:javascript
复制
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");
票数 104
EN

Stack Overflow用户

发布于 2012-10-11 20:46:09

对于completude,您也可以轻松地完成,而无需调用任何繁重的库函数(没有snprintf、strcat,甚至是memcpy)。例如,如果您正在编写一些微控制器或操作系统内核,而libc不可用,那么它可能会很有用。

如果你在谷歌上搜索,你能在周围找到类似的代码,没有什么特别的。实际上,它并不比调用snprintf复杂多少,而且速度也快得多。

代码语言:javascript
复制
#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和重复最后一个大小写代码(但终止字符被写了两次)。

代码语言:javascript
复制
#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);
}

下面是另一个版本来回答一个评论,说我使用了一个“技巧”来知道输入缓冲区的大小。实际上,这不是一种技巧,而是一种必要的输入知识(您需要知道要转换的数据的大小)。我通过将转换代码提取到一个单独的函数中,使这一点变得更加清晰。我还为目标缓冲区添加了边界检查代码,如果我们知道我们在做什么,那么这并不是真正必要的。

代码语言:javascript
复制
#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);
}
票数 35
EN

Stack Overflow用户

发布于 2016-12-16 04:59:17

上面已经存在类似的答案,我添加了这个答案来解释下面这行代码是如何工作的:

代码语言:javascript
复制
ptr += sprintf(ptr, "%02X", buf[i])

这很复杂,也不容易理解,我在下面的评论中做了解释:

代码语言:javascript
复制
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.
     *
     * We don't need to add a terminating null byte because it's been already 
     * added for us from the last hex string. */  
    ptr += sprintf(ptr, "%02X", buf[i]);
}

printf("%s\n", output);
票数 24
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6357031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档