Для комплектуди ви також можете легко це зробити, не викликаючи жодної важкої функції бібліотеки (ні snprintf, ні strcat, навіть memcpy). Це може бути корисно, скажімо, якщо ви програмуєте якийсь мікроконтролер або ядро ОС, де libc недоступний.
Нічого по-справжньому вигадливого, навколо ви можете знайти подібний код, якщо погуглити. Насправді це не набагато складніше, ніж виклик snprintf, і набагато швидше.
#include <stdio.h>
int main(){
unsigned char buf[] = {0, 1, 10, 11};
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};
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){
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);
}
buf[i]
повинен бутиunsigned char
buf[i] > 127
buf_ptr += sprintf(buf_ptr, "%02X", (unsigned char)buf[i]);