Hex to char array in C

2019-01-09 11:02发布

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 ... };

标签: c arrays char hex
9条回答
虎瘦雄心在
2楼-- · 2019-01-09 11:10

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).

查看更多
祖国的老花朵
3楼-- · 2019-01-09 11:12

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;
}
查看更多
劳资没心,怎么记你
4楼-- · 2019-01-09 11:15

First, your question isn't very precise. Is the string a std::string or 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.

查看更多
够拽才男人
5楼-- · 2019-01-09 11:24
{
    char szVal[] = "268484927472";
    char szOutput[30];

    size_t nLen = strlen(szVal);
    // Make sure it is even.
    if ((nLen % 2) == 1)
    {
        printf("Error string must be even number of digits %s", szVal);
    }

    // Process each set of characters as a single character.
    nLen >>= 1;
    for (size_t idx = 0; idx < nLen; idx++)
    {
        char acTmp[3];
        sscanf(szVal + (idx << 1), "%2s", acTmp);
        szOutput[idx] = (char)strtol(acTmp, NULL, 16);
    }
}
查看更多
Viruses.
6楼-- · 2019-01-09 11:24

Let's say this is a little-endian ascii platform. Maybe the OP meant "array of char" rather than "string".. We work with pairs of char and bit masking.. note shiftyness of x16..

/* not my original work, on stacko somewhere ? */

for (i=0;i < 4;i++) {

    char a = string[2 * i];
    char b = string[2 * i + 1];

    array[i] = (((encode(a) * 16) & 0xF0) + (encode(b) & 0x0F));
 }

and function encode() is defined...

unsigned char encode(char x) {     /* Function to encode a hex character */
/****************************************************************************
 * these offsets should all be decimal ..x validated for hex..              *
 ****************************************************************************/
    if (x >= '0' && x <= '9')         /* 0-9 is offset by hex 30 */
        return (x - 0x30);
    else if (x >= 'a' && x <= 'f')    /* a-f offset by hex 57 */
        return(x - 0x57);
    else if (x >= 'A' && x <= 'F')    /* A-F offset by hex 37 */
        return(x - 0x37);
}

This approach floats around elsewhere, it is not my original work, but it is old. Not liked by the purists because it is non-portable, but extension would be trivial.

查看更多
爱情/是我丢掉的垃圾
7楼-- · 2019-01-09 11:33

If the string is correct and no need to keep its content then i would do it this way:

#define hex(c) ((*(c)>='a')?*(c)-'a'+10:(*(c)>='A')?*(c)-'A'+10:*(c)-'0') 

void hex2char( char *to ){
  for(char *from=to; *from; from+=2) *to++=hex(from)*16+hex(from+1);
  *to=0;
}

EDIT 1: sorry, i forget to calculate with the letters A-F (a-f)

EDIT 2: i tried to write a more pedantic code:

#include <string.h> 

int xdigit( char digit ){
  int val;
       if( '0' <= digit && digit <= '9' ) val = digit -'0';
  else if( 'a' <= digit && digit <= 'f' ) val = digit -'a'+10;
  else if( 'A' <= digit && digit <= 'F' ) val = digit -'A'+10;
  else                                    val = -1;
  return val;
}

int xstr2str( char *buf, unsigned bufsize, const char *in ){
  if( !in ) return -1; // missing input string

  unsigned inlen=strlen(in);
  if( inlen%2 != 0 ) return -2; // hex string must even sized

  for( unsigned i=0; i<inlen; i++ )
    if( xdigit(in[i])<0 ) return -3; // bad character in hex string

  if( !buf || bufsize<inlen/2+1 ) return -4; // no buffer or too small

  for( unsigned i=0,j=0; i<inlen; i+=2,j++ )
    buf[j] = xdigit(in[i])*16 + xdigit(in[i+1]);

  buf[inlen/2] = '\0';
  return inlen/2+1;
}

Testing:

#include <stdio.h> 

char buf[100] = "test";

void test( char *buf, const char *s ){
   printf("%3i=xstr2str( \"%s\", 100, \"%s\" )\n", xstr2str( buf, 100, s ), buf, s );
}

int main(){
  test( buf,      (char*)0   );
  test( buf,      "123"      );
  test( buf,      "3x"       );
  test( (char*)0, ""         );
  test( buf,      ""         );
  test( buf,      "3C3e"     );
  test( buf,      "3c31323e" );

  strcpy( buf,    "616263"   ); test( buf, buf );
}

Result:

 -1=xstr2str( "test", 100, "(null)" )
 -2=xstr2str( "test", 100, "123" )
 -3=xstr2str( "test", 100, "3x" )
 -4=xstr2str( "(null)", 100, "" )
  1=xstr2str( "", 100, "" )
  3=xstr2str( "", 100, "3C3e" )
  5=xstr2str( "", 100, "3c31323e" )
  4=xstr2str( "abc", 100, "abc" )
查看更多
登录 后发表回答