Oystein
Oystein

Reputation: 1322

c - How to set limits for strtol

I'm trying out strtol to convert parts of a uint8_t array containing ASCII HEX values to integer values. Meaning that bytes received on the serial port is formatted "89ABC" etc. in ASCII values.

But strtol converts the whole rest of the received uint8_t array from the start position, giving me a completely wrong value. So I have to do it like this:

tempvalue = MerdPC.buf[15]; MerdPC.tiltcmd=(uint8_t)strtol(&tempvalue, NULL, 16);
tempvalue = MerdPC.buf[16]; MerdPC.tiltparam=((uint16_t)strtol(&tempvalue, NULL, 16))<<8;
tempvalue = MerdPC.buf[17]; MerdPC.tiltparam|=((uint16_t)strtol(&tempvalue, NULL, 16))<<4;
tempvalue = MerdPC.buf[18]; MerdPC.tiltparam|=(uint16_t)strtol(&tempvalue, NULL, 16);

And this works. But is there a better approach to this, not involving a temp variable?

EDIT:

Input string example is:

HEX values: 23 31 43 30 30 30 30 30 30 30 30 30 30 30 30 31 37 38 39 0D 0A

ASCII: #1C0000000000001789..

The four bold characters are tiltcmd byte and tiltparam bytes respectively.

Upvotes: 0

Views: 1384

Answers (1)

Jabberwocky
Jabberwocky

Reputation: 50831

Does this help?

char tiltparam[] = "#1C0000000000001789..";

char temp[5] = { 0 };
strncpy(temp, &tiltparam[15], 4);
int tempvalue = strtol(temp, NULL, 10);
...

We still need the temp buffer, but it's shorter and more readable than your solution.

Or if you have more conversions like this one in other places, you could make a function:

int ExtractHex(const char *hexstr, int offset)
{
    char temp[5] = { 0 };
    strncpy(temp, &hexstr[offset], 4);
    return strtol(temp, NULL, 10);
}
...
int somevalue = ExtractHex(tiltparam, 15);
...

Upvotes: 1

Related Questions