Click here to Skip to main content
16,017,899 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I'm having great difficulty changing a hex value into an integer.

In an unsigned char INBuffer[2], there is a hex code in the format 0x0a etc. I would like to convert this value into a long or int variable using the strtol function:

C#
long int strtol ( const char * str, char ** endptr, int base );


For this I'm assuming I need to get the value contained within INBuffer[2] into a string pointer, but no matter how many examples I look up i just can't seem to get my head around pointers. Could somebody please help?

M.
Posted
Updated 3-Aug-11 3:13am
v2
Comments
CPallini 3-Aug-11 9:31am    
What exactly INBuffer contains? Could you be more precise (it cannot contain the string "0x0a", do you mean INBuffer[0]='0', INBuffer[1]='a'?)?

That seems a little confused to me: an unsigned char buffer with two elements can't hold a hex code in the format "0x0a" since that is four characters.

If you mean that there is a value in the two unsigned chars that equates to the hex value 0A, and that it has a range between 0000 and FFFF hex, then you need to do this:
C++
int i = ((int) INBuffer[0] & 0xFF) + (((int) INBuffer[1] << 8) & 0xFF00);

(The ANDs are there to prevent sign extentions, which shouldn't happen anyway) You may need to swap round the array indexes depending on your data format: big- or little-endian

If you mean that INBuffer contains two bytes which are '0' and 'A' respectively, then you need to copy them to a character array big enough to hold three bytes, and make it a null terminated string:
C++
unsigned char data[3];
data[0] = INBuffer[0];
data[1] = INBuffer[1];
data[2] = '\0';
You can then use that to convert it to a int:
C++
char * pEnd;
long int i = strtol(data, &pEnd, 16);
 
Share this answer
 
I'm confused by your question, but let's try this...

You have an unsigned char INBuffer[2]. This means it's a two character buffer. The two elements of this buffer can be accessed individually by using INBuffer[0] and INBuffer[1].

If you want the decimal value contained in INBuffer[0], you can do this
int buf0val = (int)INBuffer[0];

Likewise if you want the value contained in the second character of this buffer, you can do this
int buf1val = (int)INBuffer[1]


However if you mean that the first character contains the ASCII number 0 and the second character contains the ASCII 'A', the you have a different problem.

You can't use strtol on this, because this (two character) string is not NULL terminated - just as OriginalGriff said above.

Hope that helps.
 
Share this answer
 
Comments
kutalinelucas 3-Aug-11 12:25pm    
i can absolutly see where you are all coming from, the thing that is onfusing me is that if I compaire the contents of INBuffer[2] with say 0x02 (if that is what I program the firmware to return) I can find a match, where I thought each slot of an array could contain only one character. The INBuffer is declaired as 'unsigned char INBuffer[64]...why is a complete mistery to me. Guess I'll just have to put in a massive switch statement to test its contents as above.
krmed 3-Aug-11 13:14pm    
I think you are sadly confused. If you compare INBuffer[2] with 0x02 like this

if (INBuffer[2] == 0x02)you are comparing only a single BYTE.

Each character of INBuffer can only contain ONE character. It's only one byte long. How that charcter is represented is a different matter. Let's say INBuffer[2] contains the letter A.

Here are some of the ways that can be represented:

Decimal representation 65
Hexadecimal representation 0x41

ASCII representation A
Octal representation 0101

Binary representation 1000001

So you see, 0x0A is really a decimal value of 10, which is stored in a single byte. However "0x0A" (as a string) is a character string that is 4 bytes long, plus one byte for the terminating null. To show this stored in INBuffer, you would have:

INBuffer[0] = '0' or 0x30 or 48, etcINBuffer[1] = 'x' or 0x78 or 120, etc

INBuffer[2] = '0' or 0x30 or 48, etcINBuffer[3] = 'A' or 0x41 or 65, etc

INBuffer[4] = 0 (the terminating NULL)

As you can see, each individual character contains a value between 0 and 255, and this can be stored in a single byte.

Hope this helps.
kutalinelucas 3-Aug-11 16:45pm    
Sorry for the late reply, I had work to go to...but so simple! thankyou sooo much for that, you've saved me hours of head scratching
I think You can do like this,

C#
char*chVal  = "0x0a";
cout<<"size:: "<<sizeof(chVal)<<endl;
long lVal = strtol(chVal, NULL, 16);
 
Share this answer
 
Did you by any means notice that a 0x0a is four characters while your input buffer is declared as char INBuffer[2] which can hold only 2 characters?

C++
/* simple strtol example */
#include <stdio.h>
#include <stdlib.h>
int main ()
{
    char INBuffer[] = "0x0a 0xff";
    char * endOfScan;
    long int l1, l1;
    l1 = strtol (INBuffer,  &endOfScan, 16);
    l2 = strtol (endOfScan, &endOfScan, 16);
    printf ("The decimal equivalents of %s are: %ld and %ld.\n", INBuffer, l1, l2);
    return 0;
}


The endPtr parameters is used to tell where the scanner stopped recognizing a long the last time it was called. That's why it is passed as a pointer to a pointer. When you now pass the address of variable endOfScan this character pointer will point to the last char the scanner didn't recognize as belonging to the last long.

Cheers! I hope this helped.

—MRB
 
Share this answer
 

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