Per completezza, puoi anche farlo facilmente senza chiamare alcuna funzione di libreria pesante (no snprintf, no strcat, nemmeno memcpy). Può essere utile, ad esempio se stai programmando un microcontrollore o un kernel del sistema operativo in cui libc non è disponibile.
Niente di veramente strano che tu possa trovare codice simile in giro se lo cerchi su google. In realtà non è molto più complicato che chiamare snprintf e molto più veloce.
#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);
}
Ecco un'altra versione leggermente più breve. Evita semplicemente la variabile di indice intermedia i e la duplicazione dell'ultimo codice case (ma il carattere di terminazione viene scritto due volte).
#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);
}
Di seguito è riportata un'altra versione per rispondere a un commento che dice che ho usato un "trucco" per conoscere la dimensione del buffer di input. In realtà non è un trucco ma una conoscenza di input necessaria (devi conoscere la dimensione dei dati che stai convertendo). L'ho reso più chiaro estraendo il codice di conversione in una funzione separata. Ho anche aggiunto il codice di controllo dei limiti per il buffer di destinazione, che non è realmente necessario se sappiamo cosa stiamo facendo.
#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]
deve essere gettato suunsigned char
, obuf[i] > 127
buf_ptr += sprintf(buf_ptr, "%02X", (unsigned char)buf[i]);