Click here to Skip to main content
15,356,098 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi All,

I have a method in my code which takes a void* as parameter.
to pass a hexa decimal value it is using the following code.
I am not able to understand why it was written like that.
I tried to print the value (FinalValue) it is printing some symbols like

0x006a4ba0 "Ì" "Ì"

Could you please explain me any suggestion/ideas on this below code ?
Will the below code work for big hexa decimal string like "0xFFFFFFFFFFFFFFFF"
without any code change ??
I am not able to understand why it is taking half of the length of original string.

Basically i could not understand it's output/intention.
Appreciate your help .

C++
void main() 
{ 
	//std::string seedStr = "0xFFFFFFFFFFFFFFFF"; 
	std::string strValue = "0x12"; 
	int strValuelen = 0; 
	unsigned char* FinalValue= new unsigned char[(strValue.length()/2)+1]; 
	memset(FinalValue,0, (strValue.length()/2)+1); 

	//convert the strValue to hex 
	char* strValueHex = (char*)strValue.c_str(); 
	int temp; 

    for(unsigned int i = 0; i < strValue.length()/2; ++i )
    { 
       sscanf( strValueHex + 2 * i, "%2x", &temp );
       FinalValue[i] = temp; 
    } 

   std::cout << FinalValue);
   getch(); 
}
Posted

You seem to be mixing up and/or not understand the concepts of the value of variable, how it is stored, and how it is represented on screen in a hexadecimal, decimal, or other form of representation. I strongly suggest you should read up on number bases, e. g. at http://en.wikipedia.org/wiki/Radix[^].

Now on to your code:
1. the input string is defined as "0x12". This is the hexadecimal representation of the number 18. The leading "0x" is not an actual part of the number, it is only an indication that the string is a hexadecimal number. As such, it should be skipped when trying to interpret the value! That is what Carlo meant when he said you should feed only "12" to your algorithm, rather than "0x12".

2. You've defined FinalValue to be of tpye "array of unsigned char". This is fine if your purpose is to compactly store a number of any kind or any length. But it is pointless if your purpose is to interpret a hexadecimal number and print it in readable (i. e. decimal) form. But let's ignore the latter for the moment:

Hexadecimal numbers are commonly used to represent the content of blocks of memory of arbitrary length. The reason is that memory is organized in bytes, and each byte can hold a value between 0 and 255, and a pair of hexadecimal digits can perfectly represent that range. So, when you use a tool to look at the contents of some memory block, you'll likely see it arranged in pairs of hexadecimal numbers, where each pair represents the value of one byte of memory.

Your algorithm appears to be doing the opposite, i. e. reading pairs of hexadecimal digits, and convert them back into the byte value they represent. And that value is then stored in FinalValue.

3. Your code breaks down when you try to print out the contents of your reinterpreted byte sequence: cout knows how to print out any basic type, such as a single int, float, or (unsigned) char. You pass an array of unsigend char however, and that is interpreted by cout as a 0-terminated C-style string! I. e. it will keep on reading each byte, reinterpret it as a printable character, print that character, and repeat until it encounters a byte with the value of 0. Now, printing an arbitrary value of a byte as a printable character is something that you definitely didn't intend her, and besides, it isn't always possible: some byte values don't correspond to any printable character! Read up on http://en.wikipedia.org/wiki/Character_encoding[^] for more information.

4. There's also the added problem that FinalValue is just long enough to hold the reinterpreted byte sequence - 1 byte in this case. It does not have sufficient space to also hold the terminating 0-character that cout expects, therefore cout keeps on reading the memory beyond the end of Finalvalue until it eventually encounters a 0-byte at some arbitrary location. Of course, the resulting output is equally arbitrary and may even vary if you repeatedly run the program.

Lessons learned:
a) If you pass an array of char to cout, it will be interpreted as a C-style 0-terminated string, and is expected to be terminated with a 0-byte.
b) A C-style string must allocate one additional byte on top of the length of the stored string to hold the terminating 0-byte.
c) You must ensure that the end of the actual string stored in a C-style string is followed by a 0-byte.
d) If your purpose of a char array is not to store actual characters, you don't need the terminating 0, but you passing it to cout will output garbage.

5. One thing I can't answer is how to print out FinalValue correctly: it depends what you wanted to see. If your input was meant to be just an arbitrary sequence of hexadecimal digits, of arbitrary length, then the best way to print this out on screen is a sequence of hexadecimal digits - i. e. the input string!

But if the input was meant to represent a single number, then your algorithm is doing the wrong thing! In that case, FinalValue should be of type int or long, not array of unsigned char!
   
Comments
Member 3975629 24-Feb-14 6:10am
   
Thanks a Lot for your explanation.

My input is a sequence of hexadecimal digits ( Eg: 0x1234567890ABCDEF), of arbitrary length, (ofcourse i will remove the 0x part before feeding it to algorithm as you suggested)

My aim is to pass the Final Value (hexadecimal char array)
to a method which takes void* as parameter.

Could you please let me know what this piece of code exactly do ?
and why it is taking half of the length ?

Please refer to the code that i already pasted in the starting of this thread.
Please ignore cout statement.

for(unsigned int i = 0; i < strValue.length()/2; ++i )
{
sscanf( strValueHex + 2 * i, "%2x", &temp );
FinalValue[i] = temp;
}

Appreciate your help.

Thanks,
Sudhakar
Stefan_Lang 24-Feb-14 7:24am
   
The function takes a string of hexadecimal digits and compresses them into a string of bytes. Since each byte can store a value between 0 and 255, it's hexadecimal representation takes two digits. Reversely, two digits make up one byte. That is why the resulting byte array is only half as long.
Member 3975629 24-Feb-14 10:25am
   
Thank you. my doubts are cleared. appreciate your help.

-Sudhakar
It looks like a (bit ugly) attempt to conver an hexadecimal string to a byte array. However, you should feed it with, for instance "12", instead of "0x12".
Moreover you shouldn't output the byte array that way, instead you should print the value of every individual byte.
Please note, allocated memory is not released.
   
Comments
Member 3975629 20-Feb-14 6:15am
   
How to print the value of every individual byte.?
Member 3975629 20-Feb-14 6:26am
   
However, you should feed it with, for instance "12", instead of "0x12".

if I feed it as "0x12" will it give wrong results ?? or should I not pass like that ?
why I am asking is my input comes like that "0x1234567890123456" .

Please let me know your suggestions on this.

Thanks.
Member 3975629 20-Feb-14 8:08am
   
Any suggestions/ideas on the above questions are Welcome.

Appreciate your Help.

Thanks.
Sudhakar

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900