views:

2103

answers:

6

Given a string of hex values i.e. e.g. "0011223344" so that's 0x00, 0x11 etc.

How do I add these values to a char array?

Equivalent to say: char array[4] = { 0x00, 0x11 ... };

A: 

First, your question isn't very precise. Is the string a std::string? A char buffer? Set at compile-time?

Dynamic memory is almost certainly your answer....

char* arr = (char*)malloc(numberOfValues);

Then, you can walk through the input and assign it to the array.

Paul Nathan
It's not a std::string - this is C and there's only one sort of string.
Jonathan Leffler
@Paul: what do you consider is useful about your answer? The question is about 'how to walk through the input and assign it to an array'...which you carefully leave as an exercise for the reader.
Jonathan Leffler
Paul Nathan
+5  A: 

You can't fit 5 bytes worth of data into a 4 byte array; that leads to buffer overflows.

If you have the hex digits in a string, you can use sscanf() and a loop:

#include <stdio.h>
#include <ctype.h>

int main()
{
    const char *src = "0011223344";
    char buffer[5];
    char *dst = buffer;
    char *end = buffer + sizeof(buffer);
    unsigned int u;

    while (dst < end && sscanf(src, "%2x", &u) == 1)
    {
        *dst++ = u;
        src += 2;
    }

    for (dst = buffer; dst < end; dst++)
        printf("%d: %c (%d, 0x%02x)\n", dst - buffer,
               (isprint(*dst) ? *dst : '.'), *dst, *dst);

    return(0);
}

Note that printing the string starting with a zero-byte requires care; most operations terminate on the first null byte. Note that this code did not null-terminate the buffer; it is not clear whether null-termination is desirable, and there isn't enough space in the buffer I declared to add a terminal null (but that is readily fixed). There's a decent chance that if the code was packaged as a subroutine, it would need to return the length of the converted string (though you could also argue it is the length of the source string divided by two).

Jonathan Leffler
This is a great answer! Thanks! :D
schultkl
+3  A: 
sambowry
This assumes you are allowed to modify the string, and does the translation in situ, and null terminates the converted string. Since the first byte is null, you probably need to return the number of converted characters.
Jonathan Leffler
You are true, but the question does not formulate requirements, so this code is good enough ;-)
sambowry
You might want to consider supporting hex digits above 9, too. If the only string required to work is the one given in the question, then obviously the most concise answer is `char array[] = {0, 17, 34, 51, 68};`. But I think when the questioner said "i.e.", he actually meant "e.g."
Steve Jessop
A: 

Fatalfloor...

There are a couple of ways to do this... first, you can use memcpy() to copy the exact representation into the char array.

You can use bit shifting and bit masking techniques as well. I'm guessing this is what you need to do as it sounds like a homework problem.

Lastly, you can use some fancy pointer indirection to copy the memory location you need.

All of these methods are detailed here:

http://stackoverflow.com/questions/1522994/store-an-int-in-a-char-array

Polaris878
Would you care to clarify how memcpy() can be used?
Jonathan Leffler
A: 

I would do something like this;

// Convert from ascii hex representation to binary
// Examples;
//   "00" -> 0
//   "2a" -> 42
//   "ff" -> 255
// Case insensitive, 2 characters of input required, no error checking
int hex2bin( const char *s )
{
    int ret=0;
    int i;
    for( i=0; i<2; i++ )
    {
        char c = *s++;
        int n=0;
        if( '0'<=c && c<='9' )
            n = c-'0';
        else if( 'a'<=c && c<='f' )
            n = 10 + c-'a';
        else if( 'A'<=c && c<='F' )
            n = 10 + c-'A';
        ret = n + ret*16;
    }
    return ret;
}

int main()
{
    const char *in = "0011223344";
    char out[5];
    int i;

    // Hex to binary conversion loop. For example;
    // If in="0011223344" set out[] to {0x00,0x11,0x22,0x33,0x44}
    for( i=0; i<5; i++ )
    {
        out[i] = hex2bin( in );
        in += 2;
    }
    return 0;
}
Bill Forster
A: 

Give a best way:

Hex string to numeric value , i.e. str[] = "0011223344" to value 0x0011223344, use

value = strtoul(string, NULL, 16); // or strtoull()

done. if need remove beginning 0x00, see below.

though for LITTLE_ENDIAN platforms, plus: Hex value to char array, value 0x11223344 to char arr[N] = {0x00, 0x11, ...}

unsigned long *hex = (unsigned long*)arr;
*hex = htonl(value);
// you'd like to remove any beginning 0x00
char *zero = arr;
while (0x00 == *zero) { zero++; }
if (zero > arr) memmove(zero, arr, sizeof(arr) - (zero - arr));

done.

Notes: For converting long string to a 64 bits hex char arr on a 32-bit system, you should use unsigned long long instead of unsigned long, and htonl is not enough, so do it yourself as below because might there's no htonll, htonq or hton64 etc:

#if __KERNEL__
    /* Linux Kernel space */
    #if defined(__LITTLE_ENDIAN_BITFIELD)
     #define hton64(x) __swab64(x)
    #else
     #define hton64(x) (x)
    #endif
#elif defined(__GNUC__)
    /* GNU, user space */
    #if __BYTE_ORDER == __LITTLE_ENDIAN 
     #define hton64(x) __bswap_64(x)
    #else
     #define hton64(x) (x)
    #endif
#elif 
         ...
#endif

#define ntoh64(x)   hton64(x)

see http://effocore.googlecode.com/svn/trunk/devel/effo/codebase/builtin/include/impl/sys/bswap.h

EffoStaff Effo
supported max hex string length: 16 bytes/chars when beginning char is not '0'.
EffoStaff Effo