简体   繁体   中英

C Library function for converting a string of hex digits to ints?

I have a variable length string where each character represents a hex digit. I could iterate through the characters and use a case statement to convert it to hex but I feel like there has to be a standard library function that will handle this. Is there any such thing?

Example of what I want to do. "17bf59c" -> int intarray[7] = { 1, 7, 0xb, 0xf, 5, 9, 0xc}

No, there's no such function, probably because (and now I'm guessing, I'm not a C standard library architect by a long stretch) it's something that's quite easy to put together from existing functions. Here's one way of doing it decently:

int * string_to_int_array(const char *string, size_t length)
{
  int *out = malloc(length * sizeof *out);
  if(out != NULL)
  {
    size_t i;
    for(i = 0; i < length; i++)
    {
      const char here = tolower(string[i]);
      out[i] = (here <= '9') ? (here - '\0') : (10 + (here - 'a'));
    }
  }
  return out;
}

Note: the above is untested.

Also note things that maybe aren't obvious, but still subtly important (in my opinion):

  1. Use const for pointer arguments that are treated as "read only" by the function.
  2. Don't repeat the type that out is pointing at, use sizeof *out .
  3. Don't cast the return value of malloc() in C.
  4. Check that malloc() succeeded before using the memory.
  5. Don't hard-code ASCII values, use character constants.
  6. The above still assumes an encoding where 'a'..'f' are contigous, and would likely break on eg EBCDIC . You get what you pay for, sometimes. :)

using strtol

void to_int_array (int *dst, const char *hexs)
{
    char buf[2] = {0};
    char c;
    while ((c = *hexs++)) {
        buf[0] = c;
        *dst++ = strtol(buf,NULL,16);
    }
}

Here's another version that allows you to pass in the output array. Most of the time, you don't need to malloc, and that's expensive. A stack variable is typically fine, and you know the output is never going to be bigger than your input. You can still pass in an allocated array, if it's too big, or you need to pass it back up.

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

/* str of length len is parsed to individual ints into output
* length of output needs to be at least len.
* returns number of parsed elements. Maybe shorter if there
* are invalid characters in str.
*/
int string_to_array(const char *str, int *output)
{
    int *out = output;
    for (; *str; str++) {
        if (isxdigit(*str & 0xff)) {
            char ch = tolower(*str & 0xff);
            *out++ = (ch >= 'a' && ch <= 'z') ? ch - 'a' + 10 : ch - '0';
        }
    }
    return out - output;
}

int main(void)
{
    int values[10];
    int len = string_to_array("17bzzf59c", values);
    int i = 0;
    for (i = 0; i < len; i++) 
        printf("%x ", values[i]);
    printf("\n");
    return EXIT_SUCCESS;
}
#include <stdio.h>

int main(){
    char data[] =  "17bf59c";
    const int len = sizeof(data)/sizeof(char)-1;
    int i,value[sizeof(data)/sizeof(char)-1];

    for(i=0;i<len;++i)
        sscanf(data+i, "%1x",value + i);

    for(i=0;i<len;++i)
        printf("0x%x\n", value[i]);
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM