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