How to make String of hex into array of int?

Hi

What are your elegant suggestions for converting a String of hex values into an array of uint8_t?

The string of hex can be either of the below (your choice), and the number of hex values can vary.

"AA BB CC DD"

or

"AABBCCDD"

You can use either way, your choice. Using spaces is considered more elegant thought :wink:

BTW, "elegant" incorporates "efficient" :wink:

C++ strtol function

If your input has spaces you can convert each value and use the endptr parameter to step through the input.

Not if it really is a String rather than a string

It's a String, maybe I can make it a string.

It's an input from a HTML form using an Async webserver.

No worries. You can copy it into a char array and then use the strtol function.

I understand that this works:

uint8_t values[] = "\x01\x19\x01\xff\x01\x80\x54\x0D\x19\x00";

So then I wonder, would this also work?

String stringOfValues = "\x01\x19\x01\xff\x01\x80\x54\x0D\x19\x00";
uint8_t values[] = stringOfValues;

It's not exactly what I asked for, but if this very elegant solution works, I could live with that I
think :slight_smile:

uint8_t values[] = "\x01\x19\x01\xff\x01\x80\x54\x0D\x19\x00";

Why not just:

uint8_t values[] = {0x01, 0x19, 0x01, 0xff, 0x01, 0x80, 0x54, 0x0D, 0x19, 0x00};

Nope. But this will:

String stringOfValues = "\x01\x19\x01\xff\x01\x80\x54\x0D\x19\x00";
uint8_t* values = (uint8_t*)stringOfValues.c_str();

Bad programming though.

Is not really elegant. If you just need to initialize an array statically then just do it like I said in my previous response. If you want to convert a string dynamically (example: string coming from serial) to an array of values then strtol will work fine.

It comes from an html input form.

It doesn't specifically matter where it comes from. What matters is how it is stored, and whether you have any control over that.

Are the number of bytes in the string always constant and known?

Why is this bad programming?

Show me an example of its use, from any source code you like. One thing that puzzles me about it, if it's from a form, I guess you have control over the format. Why would you use an obscure C language based format for that? How is the data generated in the first place? By a machine? Human? Normally you would use CSV format or similar for something like that.

Also, that code has unnecessary conversions. I'm pretty sure you can read the data directly into a c string (array) and process it directly from there...

Also the String class can cause problems if used indiscriminately on some Arduinos with small memory footprints.

Because I cast a constant to a non-constant. If you were to actually write to memory using that pointer it would cause lots of havoc.

String input = "AA BB CC DDAABBCCDD";

byte data[100];
size_t dataIndex = 0;

void setup()
{
  Serial.begin(115200);
  delay(200);

  convert(input);

  for (size_t i = 0; i < dataIndex; i++)
  {
    Serial.print(data[i], HEX);
    Serial.print(' ');
  }
  Serial.println();
}

void convert(String hexstring)
{
  int length = hexstring.length();
  size_t digitCount = 0;

  for (int i = 0; i < length; i++)
  {
    char digit = hexstring[i];
    byte nybble = 99;

    if (digit >= '0' && digit <= '9')
    {
      nybble = digit - '0';
    }
    else if (digit >= 'A' && digit <= 'F')
    {
      nybble = digit - 'A' + 10;
    }
    else if (digit >= 'a' && digit <= 'f')
    {
      nybble = digit - 'a' + 10;
    }
    else
      nybble = 99;

    if (nybble == 99)
    {
      // Non-digit
      if (digitCount > 0)
      {
        // There was one digit in this byte already
        dataIndex++;
        data[dataIndex] = 0;
        digitCount = 0;
      }
    }
    else
    {
      // Hex Digit
      data[dataIndex] <<= 4;  // Make room for a new low digit
      data[dataIndex] += nybble;
      digitCount++;
      if (digitCount == 2)
      {
        // This byte is full
        dataIndex++;
        data[dataIndex] = 0;
        digitCount = 0;
      }
    }
  }
}

void loop() {}

Do you want to see "AABBCCDD" as AA BB CC DD (the separate hex bytes)? The following sketch saves them in the array named: byteArray[].

void setup()
{
  Serial.begin(9600);
  char data[] = "AABBCCDD";

  unsigned long x = strtoul(data, NULL, 16);
  //Serial.println(x, HEX);//AABBCCDD
  int i = 0;
  byte byteArray[4];

  do
  {
    byteArray[i] = x % 0x100;
    x = x / 0x100;
    i++;
  }
  while (x != 0);

  for (int k = 3; k >= 0; k--)
  {
    Serial.println(byteArray[k], HEX);
  }
}

void loop() 
{

}
AA
BB
CC
DD

Aha, ok.

That is valid for this example, but if the data was comping into stringOfValues from for instance an html form, then it wouldn't be a const, right?

An example with sscanf : t949058.ino - Wokwi Arduino and ESP32 Simulator

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.