Velocity Reviews > Converting Char Array with hex values into 32-bit integer

# Converting Char Array with hex values into 32-bit integer

Martin Kleiner
Guest
Posts: n/a

 02-10-2009
Hi

I have an 8 byte array of hex characters, e.g.
['c','5','3','1','0','6','5','9'] and I wanna convert this
to an unsigned int, so that unsigned int i = 0xc5310659. I wonder if
in C there is an very easy way to do that?

One cumbersome way to do that would be:

unsigned int arrToInt = 0;

for(i=0; i<8; i++) {
arrToInt =(arrToInt<< | toIntVal(charBuffer[i]);
}

int toIntVal(char c)
{
int value = 0;

switch (c)
{
case '0':
value = 0;
break;
case '1':
value = 1;
break;
....
default:

return val;
}

has someone an easier idea?

Thanks!

Nate Eldredge
Guest
Posts: n/a

 02-10-2009
Martin Kleiner <(E-Mail Removed)> writes:

> Hi
>
> I have an 8 byte array of hex characters, e.g.
> ['c','5','3','1','0','6','5','9'] and I wanna convert this
> to an unsigned int, so that unsigned int i = 0xc5310659. I wonder if
> in C there is an very easy way to do that?

You could add a terminating nul and use the standard `strtoul'
function.

char charBuffer[8] = { 'c','5','3','1','0','6','5','9' };
char tmpbuf[9];
char *q;
unsigned long result;

memcpy(tmpbuf, charBuffer, ;
tmpbuf[8] = '\0';
result = strtoul(tmpbuf, &q, 16);
if (q != &tmpbuf[8])
fprintf(stderr, "Didn't convert 8 characters\n");

Martin Ambuhl
Guest
Posts: n/a

 02-10-2009
Martin Kleiner wrote:
> Hi
>
> I have an 8 byte array of hex characters, e.g.
> ['c','5','3','1','0','6','5','9'] and I wanna convert this
> to an unsigned int, so that unsigned int i = 0xc5310659. I wonder if
> in C there is an very easy way to do that?

The easy way is to have your 8 chars put into a string:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stddef.h>

int main(void)
{
/* note that the buffer is, as specifed 8 chars longs, so it is not a
string. Were this declared with buff[], the trailing '\0' would
have been supplied, and strtoul would do. */
char buff[8] = "c5310659";
/* note that the target is an unsigned long. An unsigned int, as the
OP used, is allowed to have a maximum of 65535 (0xFFFF) so is
inappropriate */
unsigned long target;
char cvt[] = "0123456789abcdef";
/* a 9-byte buffer for another approach */
char ninebytes[8];
size_t i;
char *p;
ptrdiff_t j;
_Bool crap = 0;

/* approach 1 */
for (i = 0, target = 0; i < 8; i++) {
p = strchr(cvt, tolower(buff[i]));

if (!p) {
crap = 1;
printf("The character '%c' is not appropriate.\n", buff[i]);
break;
}
j = p - cvt;
target = (target << 4) + j;
}
if (crap)
printf
("warning, I stopped converting after the above error
message\n");
printf("Approach 1:\n"
"The value of \"c5310569\" appears to be %lu (%#lx"
" %#lo)\n\n",
target, target, target);

/* approach 2 */
/* make a string */
memcpy(ninebytes, buff, ;
ninebytes[8] = 0;
target = strtoul(ninebytes, &p, 16);
if (*p) {
printf("There is an unconverted part of \"%s\" remaining,\n"
"namely \"%s\"\n", buff, p);
}
printf("Approach 2:\n"
"The value of \"c5310569\" appears to be %lu (%#lx"
" %#lo)\n\n",
target, target, target);

return 0;
}

Approach 1:
The value of "c5310569" appears to be 3308324441 (0xc5310659 030514203131)

Approach 2:
The value of "c5310569" appears to be 3308324441 (0xc5310659 030514203131)

Ben Bacarisse
Guest
Posts: n/a

 02-11-2009
Martin Kleiner <(E-Mail Removed)> writes:

> I have an 8 byte array of hex characters, e.g.
> ['c','5','3','1','0','6','5','9'] and I wanna convert this
> to an unsigned int, so that unsigned int i = 0xc5310659. I wonder if
> in C there is an very easy way to do that?

Yes:

char hex[8] = {'c','5','3','1','0','6','5','9'};
unsigned int n;
if (sscanf(hex, "%8x", &n) == 1)
/* OK, use the number */

This is one of the few places where a member of the *scanf family wins
over the strto* functions.

--
Ben.

CBFalconer
Guest
Posts: n/a

 02-11-2009
Ben Bacarisse wrote:
> Martin Kleiner <(E-Mail Removed)> writes:
>
>> I have an 8 byte array of hex characters, e.g.
>> ['c','5','3','1','0','6','5','9'] and I wanna convert this
>> to an unsigned int, so that unsigned int i = 0xc5310659. I
>> wonder if in C there is an very easy way to do that?

>
> Yes:
>
> char hex[8] = {'c','5','3','1','0','6','5','9'};
> unsigned int n;
> if (sscanf(hex, "%8x", &n) == 1)
> /* OK, use the number */
>
> This is one of the few places where a member of the *scanf
> family wins over the strto* functions.

Assuming int is a 32 bit quantity. Simpler to use long

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>

Richard
Guest
Posts: n/a

 02-11-2009
CBFalconer <(E-Mail Removed)> writes:

> Ben Bacarisse wrote:
>> Martin Kleiner <(E-Mail Removed)> writes:
>>
>>> I have an 8 byte array of hex characters, e.g.
>>> ['c','5','3','1','0','6','5','9'] and I wanna convert this
>>> to an unsigned int, so that unsigned int i = 0xc5310659. I
>>> wonder if in C there is an very easy way to do that?

>>
>> Yes:
>>
>> char hex[8] = {'c','5','3','1','0','6','5','9'};
>> unsigned int n;
>> if (sscanf(hex, "%8x", &n) == 1)
>> /* OK, use the number */
>>
>> This is one of the few places where a member of the *scanf
>> family wins over the strto* functions.

>
> Assuming int is a 32 bit quantity. Simpler to use long

Actually does someone have a pointer (or reference ...) to a good
summary of C min/max values with explanations.

Nate Eldredge
Guest
Posts: n/a

 02-11-2009
Richard <(E-Mail Removed)> writes:

> CBFalconer <(E-Mail Removed)> writes:
>
>> Ben Bacarisse wrote:
>>> Martin Kleiner <(E-Mail Removed)> writes:
>>>
>>>> I have an 8 byte array of hex characters, e.g.
>>>> ['c','5','3','1','0','6','5','9'] and I wanna convert this
>>>> to an unsigned int, so that unsigned int i = 0xc5310659. I
>>>> wonder if in C there is an very easy way to do that?
>>>
>>> Yes:
>>>
>>> char hex[8] = {'c','5','3','1','0','6','5','9'};
>>> unsigned int n;
>>> if (sscanf(hex, "%8x", &n) == 1)
>>> /* OK, use the number */
>>>
>>> This is one of the few places where a member of the *scanf
>>> family wins over the strto* functions.

>>
>> Assuming int is a 32 bit quantity. Simpler to use long

>
> Actually does someone have a pointer (or reference ...) to a good
> summary of C min/max values with explanations.

Sections 1.1-1.4 of the C FAQ at http://c-faq.com/decl/index.html has
some good info. Most relevant here is that `unsigned int' could be
smaller than 32 bits. `unsigned long' is guaranteed to be at least that
big, but could be bigger.

<limits.h> contains macros giving the limits for the standard integer
types.

<stdint.h> has typedefs for integer types with various properties, and
<inttypes.h> contains macros for using them with printf.

If you have full C99 available to you, the best way to do this might be:

#include <inttypes.h>
#include <stdio.h>

char hex[8] = {'c','5','3','1','0','6','5','9'};
uint_fast32_t n;
if (sscanf(hex, "%8" SCNxFAST32, &n) == 1)
/* ok */

uint_fast32_t is defined to be the most efficient integer type that's at
least 32 bits, and SCNxFAST32 is the scanf specifier for that type in
hex.

Boon
Guest
Posts: n/a

 02-11-2009
Richard wrote:

> Actually does someone have a pointer (or reference ...) to a good
> summary of C min/max values with explanations.

Here are those I occasionally use.
http://home.att.net/~jackklein/c/inttypes.html
http://www.dinkumware.com/manuals/?page=limits.html

Spiros Bousbouras
Guest
Posts: n/a

 02-11-2009
On 10 Feb, 18:32, Martin Ambuhl <(E-Mail Removed)> wrote:
> Martin Kleiner wrote:
> > Hi

>
> > I have an 8 byte array of hex characters, e.g.
> > ['c','5','3','1','0','6','5','9'] and I wanna convert this
> > to an unsigned int, so that unsigned int i = 0xc5310659. I wonder if
> > in C there is an very easy way to do that?

>
> The easy way is to have your 8 chars put into a string:
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <ctype.h>
> #include <string.h>
> #include <stddef.h>
>
> int main(void)
> {
> /* note that the buffer is, as specifed 8 chars longs, so it is not a
> string. Were this declared with buff[], the trailing '\0' would
> have been supplied, and strtoul would do. */
> char buff[8] = "c5310659";
> /* note that the target is an unsigned long. An unsigned int, as the
> OP used, is allowed to have a maximum of 65535 (0xFFFF) so is
> inappropriate */
> unsigned long target;
> char cvt[] = "0123456789abcdef";
> /* a 9-byte buffer for another approach */
> char ninebytes[8];
> size_t i;
> char *p;
> ptrdiff_t j;
> _Bool crap = 0;
>
> /* approach 1 */
> for (i = 0, target = 0; i < 8; i++) {
> p = strchr(cvt, tolower(buff[i]));
>
> if (!p) {
> crap = 1;
> printf("The character '%c' is not appropriate.\n", buff[i]);
> break;
> }
> j = p - cvt;
> target = (target << 4) + j;
> }
> if (crap)
> printf
> ("warning, I stopped converting after the above error
> message\n");
> printf("Approach 1:\n"
> "The value of \"c5310569\" appears to be %lu (%#lx"
> " %#lo)\n\n",
> target, target, target);
>
> /* approach 2 */
> /* make a string */
> memcpy(ninebytes, buff, ;
> ninebytes[8] = 0;

char ninebytes[8];

Spiros Bousbouras
Guest
Posts: n/a

 02-11-2009
On 10 Feb, 16:20, Martin Kleiner <(E-Mail Removed)> wrote:
> Hi
>
> I have an 8 byte array of hex characters, e.g.
> ['c','5','3','1','0','6','5','9'] and I wanna convert this
> to an unsigned int, so that unsigned int i = 0xc5310659. I wonder if
> in C there is an very easy way to do that?
>
> One cumbersome way to do that would be:
>
> unsigned int arrToInt = 0;
>
> for(i=0; i<8; i++) {
> arrToInt =(arrToInt<< | toIntVal(charBuffer[i]);
>
> }
>
> int toIntVal(char c)
> {
> int value = 0;
>
> switch (c)
> {
> case '0':
> value = 0;
> break;
> case '1':
> value = 1;
> break;
> ....
> default:
>
> return val;
>
> }
>
> has someone an easier idea?

Apart from the other suggestions, you can write
int toIntVal(char c)
{
int value = 0;

if ( '0' <= c && c <= '9' ) {
value = c - '0' ;
} else {
switch (c)
{
case 'a':
value = 10;
break;
case 'b':
value = 11;
break;
....
default:
/* Handle error */
return val;

}

Personally I wouldn't use value at all but write