Для полноты, вы также можете легко сделать это без вызова какой-либо тяжелой библиотечной функции (без 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]);