I am using this as a learning exercise primarily and want to ensure my code is optimal. The main thing is that it is reliable and I am made aware of any flaws.
Could it be made more efficient or more readable? How about style?
I thought about returning a char*
, but then the caller would have to think to deallocate the returned string. I saw this as a problem, so I left to caller to allocate and deallocate. Is that the right decision? Any comments?
/* Generate hex string from integer. Odd number of characters must be preceded
with zero character
Eg. 9 becomes "09", 10 becomes "0A" and 16 becomes "10"
*/
#include <stdio.h>
unsigned int num_hex_digits(unsigned int n) {
int ret = 0;
while(n) {
n >>= 4;
++ret;
}
return ret;
}
void make_hex_string_easy(unsigned int invokeid, char** xref)
{
int pad = 0;
int len = num_hex_digits(invokeid);
/* if odd number, add 1 - zero pad number */
if(len % 2 != 0)
pad = 1;
sprintf(*xref, "%s%X", pad ? "0" : "", invokeid);
}
void make_hex_string_learning(unsigned int invokeid, char** xref)
{
char* p = *xref;
int pad = 0;
int len = num_hex_digits(invokeid);
/* if odd number, add 1 - zero pad number */
if(len % 2 != 0)
pad = 1;
/* move to end of number string */
p+= len + pad - 1;
while(invokeid) {
int tmp = invokeid & 0xF;
if(tmp < 10)
*p = tmp + '0';
else
*p = tmp + 'A' - 10;
invokeid >>= 4;
p--;
}
if(pad) {
*p = '0';
}
}
int main() {
unsigned int testdata[] = {~0, 1, 255, 256, 0xFFFE, 0xFFFF, 0x10000, 0xABC };
int sz = sizeof(testdata) / sizeof(int);
int i;
char* test = (char*) calloc (20, 1);
printf("Using sprintf method\n");
for(i = 0; i < sz; ++i) {
make_hex_string_easy(testdata[i], &test);
printf("hex string of %#10x = \t%10s\n", testdata[i], test);
memset(test, 0, 20);
}
printf("\nUsing homegrown method\n");
for(i = 0; i < sz; ++i) {
make_hex_string_learning(testdata[i], &test);
printf("hex string of %#10x = \t%10s\n", testdata[i], test);
memset(test, 0, 20);
}
free(test);
return 0;
}
Output on my PC:
Using sprintf method hex string of 0xffffffff = FFFFFFFF hex string of 0x1 = 01 hex string of 0xff = FF hex string of 0x100 = 0100 hex string of 0xfffe = FFFE hex string of 0xffff = FFFF hex string of 0x10000 = 010000 hex string of 0xabc = 0ABC Using homegrown method hex string of 0xffffffff = FFFFFFFF hex string of 0x1 = 01 hex string of 0xff = FF hex string of 0x100 = 0100 hex string of 0xfffe = FFFE hex string of 0xffff = FFFF hex string of 0x10000 = 010000 hex string of 0xabc = 0ABC
invokeid
to something more clear and relevant to its role in the function. I'll write an actual answer in a few minutes. \$\endgroup\$