n.b. I know that this question has been asked on StackOverflow before in a variety of different ways and circumstances, but the search for the answer I seek doesn't quite help my specific case. So while this initially looks like a duplicate of a question such as How can I convert an integer to a hexadecimal string in C? the answers given, are accurate, but not useful to me.
My question is how to convert a decimal integer, into a hexadecimal string, manually. I know there are some beat tricks with stdlib.h and printf, but this is a college task, and I need to do it manually (professor's orders). We are however, permitted to seek help.
Using the good old "divide by 16 and converting the remainder to hex and reverse the values" method of obtaining the hex string, but there must be a big bug in my code as it is not giving me back, for example "BC" for the decimal value "188".
It is assumed that the algorithm will NEVER need to find hex values for decimals larger than 256 (or FF). While the passing of parameters may not be optimal or desirable, it's what we've been told to use (although I am allowed to modify the getHexValue function, since I wrote that one myself).
This is what I have so far:
/* Function to get the hex character for a decimal (value) between
* 0 and 16. Invalid values are returned as -1.
*/
char getHexValue(int value)
{
if (value < 0) return -1;
if (value > 16) return -1;
if (value <= 9) return (char)value;
value -= 10;
return (char)('A' + value);
}
/* Function asciiToHexadecimal() converts a given character (inputChar) to
* its hexadecimal (base 16) equivalent, stored as a string of
* hexadecimal digits in hexString. This function will be used in menu
* option 1.
*/
void asciiToHexadecimal(char inputChar, char *hexString)
{
int i = 0;
int remainders[2];
int result = (int)inputChar;
while (result) {
remainders[i++] = result % 16;
result /= (int)16;
}
int j = 0;
for (i = 2; i >= 0; --i) {
char c = getHexValue(remainders[i]);
*(hexString + (j++)) = c;
}
}
The char *hexString
is the pointer to the string of characters which I need to output to the screen (eventually). The char inputChar
parameter that I need to convert to hex (which is why I never need to convert values over 256).
If there is a better way to do this, which still uses the void asciiToHexadecimal(char inputChar, char *hexString)
function, I am all ears, other than that, my debugging seems to indicate the values are ok, but the output comes out like \377
instead of the expected hexadecimal alphanumeric representation.
Sorry if there are any terminology or other problems with the question itself (or with the code), I am still very new to the world of C.
Update: It just occurred to me that it might be relevant to post the way I am displaying the value in case its the printing, and not the conversion which is faulty. Here it is:
char* binaryString = (char*) malloc(8);
char* hexString = (char*) malloc(2);
asciiToBinary(*(asciiString + i), binaryString);
asciiToHexadecimal(*(asciiString + i), hexString);
printf("%6c%13s%9s\n", *(asciiString + i), binaryString, hexString);
(Everything in this code snip-pit works except for hexString
)
Take decimal number as dividend. Divide this number by 16 (16 is base of hexadecimal so divisor here). Store the remainder in an array (it will be: 0 to 15 because of divisor 16, replace 10, 11, 12, 13, 14, 15 by A, B, C, D, E, F respectively). Repeat the above two steps until the number is greater than zero.
To convert a Decimal value to its string representation using a specified culture and a specific format string, call the Decimal. ToString(String, IFormatProvider) method.
char getHexValue(int value) { if (value < 0) return -1; if (value > 16) return -1; if (value <= 9) return (char)value; value -= 10; return (char)('A' + value); }
You might wish to print out the characters you get from calling this routine for every value you're interested in. :) (printf(3)
format %c
.)
When you call getHexValue()
with a number between 0 and 9, you return a number between 0 and 9, in the ASCII control-character range. When you call getHexValue()
with a number between 10 and 15, you return a number between 65 and 75, in the ASCII letter range.
The sermon? Unit testing can save you hours of time if you write the tests about the same time you write the code.
Some people love writing the tests first. While I've never had the discipline to stick to this approach for long, knowing that you have to write tests will force you to write code that is easier to test. And code that is easier to test is less coupled (or 'more decoupled'), which usually leads to fewer bugs!
Write tests early and often. :)
Update: After you included your output code, I had to comment on this too :)
char* binaryString = (char*) malloc(8); char* hexString = (char*) malloc(2); asciiToBinary(*(asciiString + i), binaryString); asciiToHexadecimal(*(asciiString + i), hexString); printf("%6c%13s%9s\n", *(asciiString + i), binaryString, hexString);
hexString
has been allocated one byte too small to be a C-string -- you forgot to leave room for the ASCII NUL '\0'
character. If you were printing hexString
by the %c
format specifier, or building a larger string by using memcpy(3)
, it might be fine, but your printf()
call is treating hexString
as a string.
In general, when you see a
char *foo = malloc(N);
call, be afraid -- the C idiom is
char *foo = malloc(N+1);
That +1
is your signal to others (and yourself, in two months) that you've left space for the NUL. If you hide that +1
in another calculation, you're missing an opportunity to memorize a pattern that can catch these bugs every time you read code. (Honestly, I found one of these through this exact pattern on SO just two days ago. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With