Re: Read hex string to a buf
- From: Flash Gordon <spam@xxxxxxxxxxxxxxxxxx>
- Date: Wed, 31 Jan 2007 09:02:38 +0000
Christopher Layne wrote, On 31/01/07 04:32:
cppbeginner@xxxxxxxxx wrote:
Hello,
Newbie question: I have a string of nibbles (say 2b11cc4f5db20cd5)
that can be put as
#define DATA 0x2b11cc4f5db20cd5 or
#define DATA "2b11cc4f5db20cd5"
Need to read this into a uint8 array buf such that each byte
represents a hex digit (formed out of 2 nibbles in DATA). What do you
think is the best way to do this?
Thanks for your help.
I can think of about a 100 different ways to do it depending on how goofy you
want to get with strtol, snprintf, etc. If you don't want to use any library
functions for the actual hex work:
/*
* deadbeef.c: goofy code to convert hex bytes to unsigned char
* input should be an even number of characters or you'll fry your cpu cache.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
Another poster pointed out that unistd.h is non-standard and not required.
const size_t minl = 2;
const size_t nibl = 4;
const char delim[2] = "0x";
const char set[2][16] = { "0123456789abcdef", "0123456789ABCDEF" };
unsigned char lookup[2][256];
Why are these globals? Not critical in a standalone program, but when it gets put in to a library as this obviously would it starts becoming annoying.
int main(int argc, char **argv)
{
size_t i, l, n;
char *q;
unsigned char *p;
if (argc < 2) return -1;
if ((l = strlen((q = argv[1]))) < minl || (l & 0x01))
return -1;
Non-standard return from main. If there are multiple different failure codes there is reason for non-standard values, but that is not the case here.
return EXIT_FAILURE;
for (i = sizeof set; i--; ) {
This you corrected in a subsequent post, but just in case that gets missed:
for (i = sizeof set[0]; i--; ) {
I would for clarity use:
for (i = sizeof set[0]; i > 0; i--) {
lookup[0][(size_t)set[0][i]] = i;
lookup[0][(size_t)set[1][i]] = i;
lookup[1][i] = set[0][i];
}
if (memcmp(q, delim, minl) == 0) {
This you changed to make it insensitive to case in response to another poster.
q += minl; l -= minl;
}
if ((p = malloc(sizeof *p * l / 2)) == NULL)
return -1;
Again,
return EXIT_FAILURE;
for (i = l; i; ) {
n = lookup[0][(size_t)q[--i]] << nibl * 0;
n += lookup[0][(size_t)q[--i]] << nibl * 1;
If char is signed then yuck. Make q an unsigned char pointer and get rid of the cast here. Admittedly that means you will need a cast further up, but only the one.
p[i / 2] = n;
As a matter of style I do not see the point of n here.
}
for (l /= 2; i < l; i++) {
n = p[i];
fprintf(stdout, "p[%2.2u] == 0x%c%c %3.3u\n",
i,
lookup[1][(n & 0xf0) >> nibl * 1],
lookup[1][(n & 0x0f) >> nibl * 0],
n);
As a matter of style I do not see the point of n here either.
}
free(p);
return 0;
}
<snip>
Well, that seems to work, although it does have an undocumented assumption of an 8 bit char and I think it could misbehave on a 1s complement or sign-magnitude system. Fine for anything the OP is likely to come across unless getting in to embedded systems though where you do get 16, 24 and even 32 bit chars.
--
Flash Gordon
.
- Follow-Ups:
- Re: Read hex string to a buf
- From: Christopher Layne
- Re: Read hex string to a buf
- References:
- Read hex string to a buf
- From: cppbeginner
- Re: Read hex string to a buf
- From: Christopher Layne
- Read hex string to a buf
- Prev by Date: Re: How to improve this sort?
- Next by Date: Re: Read hex string to a buf
- Previous by thread: Re: Read hex string to a buf
- Next by thread: Re: Read hex string to a buf
- Index(es):
Relevant Pages
|