Is there a good way to parse 32 bit values out of a string? the following function does not throw the correct value and I don't know how to fix it. the value should be 170
unsigned int getvalue(const char *data, int offset)
{
unsigned int payload = 0;
for (unsigned char i = 0; i < 4; i )
{
payload <<= 8;
payload |= data[i offset];
}
return payload;
}
int value = 0x00aa;
unsigned char b1 = (value & 0xFF);
unsigned char b2 = ((value >> 8) & 0xFF);
unsigned char b3 = ((value >> 16) & 0xFF);
unsigned char b4 = ((value >> 24) & 0xFF);
int number = (b4 << 24) (b3 << 16) (b2 << 8) b1;
printf("value is: %d\n", number); // value is: 170 correct
char payload[] = "000000aa";
int value2 = getvalue(payload, 0);
printf("value is: %dn", value2); // value is: 808464432n Not correct
CodePudding user response:
if you want to convert C string containing hexadecimal number) to its integer value:
unsigned long long conv(const char *str)
{
const char digits[] = "01234567890ABCDEF";
unsigned long long result = 0;
char *ref;
while(*str)
{
result *= 16;
ref = strchr(digits, toupper((unsigned char)*str));
if(ref)
{
result = ref - digits;
}
else
{
/* error handling */
}
str ;
}
return result
}
The digits in the C string are ASCII representation of the character representing the letter or digit. '0' is not represented in the char array by zero but 0x30.
CodePudding user response:
Change your getvalue to
unsigned int getvalue(const char *data, int offset)
{
unsigned int payload = 0;
for (unsigned char i = 0; i < 8; i )
{
payload <<= 4;
if (data[i offset] >= 'a') {
payload |= (data[i offset] - 97) 10;
} else if (data[i offset] >= 'A') {
payload |= (data[i offset] - 65) 10;
} else {
payload |= (data[i offset] - 48);
}
}
return payload;
}
Each hex value occupies 4 bits, hence << 4 Each char in the string is in its ASCII code, hence the subtraction. ASCII value of 'a' is 97, but the decimal value must be 10, so the expression will be 'a' - 97 10
CodePudding user response:
There is no need to reinvent the wheel. There is a library function to do this: strtol.
#include <stdlib.h>
unsigned int getvalue(const char *data, int offset)
{
char *end;
long payload = strtol(&data[offset],&end,16);
if (*end || payload < 0 || payload > UINT_MAX) {
/* error handling */
}
return (unsigned int)payload;
}
