search HEX in String

hey there

I have an array like so

char Array[]={0x02,DATA,0x21}

where as you can see, the start byte is 0x02 and the stop byte is 0x21.
I want to extract DATA, how can I do that?

I used the code below but no lock:(

sscanf((char*)&Array[0],"0x02%s0x21",&ReadOut_Data);

You have a char array, which isn't a string (no terminating null) nor is it a String, so sscanf isn't ever going to work.

char Array[]={0x02,DATA,0x21}

Please post an example of the code that contains the array, because the line above does not even compile. Where does the data in the array come from ?

alaa72:
hey there

I have an array like so

char Array[]={0x02,DATA,0x21}

where as you can see, the start byte is 0x02 and the stop byte is 0x21.
I want to extract DATA, how can I do that?

I used the code below but no lock:(

sscanf((char*)&Array[0],"0x02%s0x21",&ReadOut_Data);

what is DATA? is it a character or or string?
if it is anything other than character type, your declaration won't work.
by knowing what type is DATA, a fix can be suggested.
maybe, you can post your full sketch here.
Thanks

from a memory perspective, DATA starts at &(Array[1]) and its length is the (sizeof Array) - 2

I think I understand. You probably want something like

char embeddedChar;
...
embeddedChar = Array[1];

aarg:
I think I understand. You probably want something like

char embeddedChar;

...
embeddedChar = Array[1];

since OP was trying to do "0x02%s0x21" I suspect DATA actually represents many bytes, may be even a cString with its trailing null char... hence my general answer #4

Clearly More info needed

aarg:
I think I understand. You probably want something like

char embeddedChar;

...
embeddedChar = Array[1];




if DATA is not a constant char type, the declaration: char Array[]={0x02,DATA,0x21} wont compile anyway.

abdelhmimas:
if DATA is not a constant char type, the declaration: char Array[]={0x02,DATA,0x21} wont compile anyway

well I assumed it was conceptual DATA is just to represent stuff in the buffer, a number of bytes. It's not actual code. May be char Array[]={0x02, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0x00, 0x21} The the message would be "Hello World"

what made me think this way was the %s in the sscanf, looks like OP was assuming a string would be there

Clearly needs OP's to jump in and clarify

Making a few assumptions I think this will do the job

char Array[] = {0x02, 0x54, 0x55, 0x21};
const size_t MAX_DATA_LEN = 100;
char dataExtracted[MAX_DATA_LEN + 1]; // add one for possible terminating null if data is really chars

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  for (int i = 10; i > 0; i--) {
    Serial.print(i);
    Serial.print(' ');
    delay(500);
  }
  Serial.println();
  size_t dataSize = sizeof(Array) - 2;
  if ( dataSize > MAX_DATA_LEN) {
    while (1) {
      Serial.print("Error!! need to make MAX_DATA_LEN larger, i.e. >="); Serial.println((sizeof(Array) - 2));
      delay(5000);
    }
  }
  memcpy(dataExtracted,Array+1,dataSize);
  dataExtracted[dataSize] = '\0'; // terminate
  Serial.println(dataExtracted);

}

void loop() {
  // put your main code here, to run repeatedly:

}

well I assumed it was conceptual DATA is just to represent stuff in the buffer, a number of bytes. It's not actual code. May be
Code: [Select]

char Array[]={0x02, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0x00, 0x21}

The the message would be "Hello World"

what made me think this way was the %s in the sscanf, looks like OP was assuming a string would be there

yes! this exactly what I meant! DATA is totally dummy like "Hello World" for example! @abdelhmimas

I have an array like so

char Array[]={0x02,DATA,0x21}

where as you can see, the start byte is 0x02 and the stop byte is 0x21.
I want to extract DATA, how can I do that?

char * array[] = {0x02, "Hello World", 0x21};

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  char * extract = array[1];
  Serial.println(extract);
}

void loop()
{
}

Try my code at #9. It does not depend on there being a terminating 0x00 and actually 'extracts' the bytes to another array.

However it depends on knowing the sizeof the Array[]

Do you really have a char Array[] = ?
OR are you reading in some data into a larger array?

Is the DATA between 0x02 and 0x21 null terminated as in #10?
Probably not if the Array is being sent to you from an external source.

If you need to duplicate the data then @drmpf code should do the job and as long as there are no null char in the payload in between your start byte and end byte and it’s ASCII then you can print it also in one go once you added the trailing null in the copy

If you don’t need to duplicate the buffer you can just replace the end marker 0x21 by 0x00 and start your printing or parsing at the index 1 instead or 0.

If you receive this payload on a stream then you could detect when to record after receiving the start marker and end the recording at the end marker. This way your buffer is ready to be used. I would suggest to study Serial Input Basics to handle this

If it is a binary protocol - probably not as 1 byte start and end marker could appear in the data - then you need to study in details the structure of the message to handle it correctly

UKHeliBob:

char * array[] = {0x02, "Hello World", 0x21};

void setup()
{
 Serial.begin(115200);
 while (!Serial);
 char * extract = array[1];
 Serial.println(extract);
}

void loop()
{
}




@Ukhelibob,
not sure this declaration is right:
char * array[] = {0x02, "Hello World", 0x21};
this one will compile
char * array[] = {"blabla", "Hello World", "blabla"};

regards

Mind the way you quote people and then write your texte. It's hard to read as you answer is embedded in the quote --> confusing

I think @Ukhelibob meant

char array[] = {0x02, "Hello World", 0x21};

that will insert the '\0' within the array and thus

  char * extract = &(array[1]);

would be our cString.

my version

char array[]={0x02, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0x00, 0x21};

had no null char embedded (and was more painful to type in :slight_smile: )

EDIT: actually on second thought

char array[] = {0x02, "Hello World", 0x21};

does not do what first look would hint at; you likely end up with 1 char in the second position which is the LSB of the constant cString memory address... does not work at all then

I think @Ukhelibob meant

Actually, the code as posted compiles and works (on a Nano at least) but probably shouldn't.
There is a warning

sketch_jan27a:8:27: error: cannot convert 'int*' to 'char*' in initialization
   char * extract = array[1];
                           ^
exit status 1
cannot convert 'const char*' to 'int*' in initialization

but the situation is saved by the compiler using the -fpermissive flag

I am still waiting to hear from the OP as to how exactly the array is populated as we are working blind here

I see - you probably have another warning

warning: invalid conversion from 'int' to 'char*' [-fpermissive]
 char * array[] = {0x02, "Hello World", 0x21};

because 0x02 and 0x21 are not pointers really

and it does not look like OP's buffer then where the payload is in the array

it does not look like OP's buffer then where the payload is in the array

I would like to know how the data gets into the array

Yes - similar thoughts in my post #13.

I think OP has all s/he needs to think about it