Go Down

Topic: compare a string to an array (Read 860 times) previous topic - next topic

Eliminateur

I have a sketch that reads a onewire memory into a 40 byte array "data[40]" that consists of alphanumeric data all together.
Now i need to compare parts of that result to known strings for my program and i've hiut a wall on how to do it more elegantly...
The parts that i need to compare are of fixed position and width.
for example, this is the content of the array, printing from 0 to 40 inside a for loop:
MAST00AC065195033CN0P975F4789096BJ174A02
i want to compare parts of it in order and do program stuff, like the MAST00 then 065 then 195  etc etc

i'd rather not have to load a variable with each letter and compare part to part ina for loop as it's tedious and takes a ton of ram and sketch space.
how can i compare part of the array to a string? like  data[0-3] == "MAST" ?

i've ben looking at string manipulation routines and somehow i'm not very convinced, for example, indexOf returns the index, so i'd need to then check if the position returned is consistent.

Or i should convert the character array to a string(or simply inputting it in a string in the first place -i need to check if the library allows this- and then using substring() paired with comparison to my reference?

Eliminateur

#1
Feb 22, 2011, 10:37 pm Last Edit: Feb 22, 2011, 10:55 pm by Eliminateur Reason: 1
As usual with these kinds of posts, i tend to be close to the answer after posting it...

found a very good info here: http://arduino.cc/en/Tutorial/StringSubstring
specially:
Code: [Select]
String stringOne = "Content-Type: text/html";

 // you can also look for a substring in the middle of a string:
 if (stringOne.substring(14,18) == "text") {
 }


now, can i use this directly on my byte array?, have to test that....

edit: no, it doesn't works, spits error: request for member 'substring' in 'data', which is of non-class type 'byte [40]'
and also breaks serial.print in HEX

edit2: aaaand more fail, i can't convert the array directly, tried using  String datos = String(data);  and returns all kinf of hocus-pocus errors of doom...

Nick Gammon

One approach is memcmp (memory compare).

eg,

Code: [Select]
void setup (void)
{
  Serial.begin (9600);
 
  char buf [] = "MAST00AC065195033CN0P975F4789096BJ174A02";
 
  byte rslt = memcmp (buf, "MAST", 4);
 
  Serial.print ("result A is ");
  Serial.println (rslt, DEC);
 
  rslt = memcmp (& buf [6], "AC", 2);
 
  Serial.print ("result B is ");
  Serial.println (rslt, DEC);
 
  rslt = memcmp (& buf [6], "XX", 2);
 
  Serial.print ("result C is ");
  Serial.println (rslt, DEC);
}


void loop (void)
{}


memcmp returns zero if the compare is equal. So the results are:

Code: [Select]
result A is 0
result B is 0
result C is 233


The first compare is from the start of the buffer. To "index in" you need the zero-relative position, and the length, like I did above.
http://www.gammon.com.au/electronics

Eliminateur

Nick,
very good tip, i'm going to try it as soon as i can!
i've also noticed a complete lack of mention to this "memcmp" function in the reference section, and it's a true shame since it made me went to strings and substrings and whatnot route :(
my worry is that you can set the starting index, but not the finish (like substring comparison), so what happens if a string portion is not on the index you set but it is further down?, it would result in a erroneus correct output.
Or does it compare AT the index for only the length defined by the last value?, i see in references for the function that it compares for said number of bytes, but i can't find if it's only for index+number of bytes only or from index to end, compare X number of bytes... i'm gonna have to do some experiments(how i wish i had an arduino simulator for these kind of things)

reference section should be far enlarged, not only for arduino-specific additions, but encompassing as much C as possible(and i know this has been mentioned several times).


robtillaart


Quote
i've also noticed a complete lack of mention to this "memcmp" function in the reference section


The Arduino environment is based upon the C++ language and almost anything of C/C++ can be used. A nice overview can be found here - http://www.nongnu.org/avr-libc/user-manual/modules.html.  Imho it is unnecessary to copy all this to the Arduino site, however a clear reference would be nice.


Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Nick Gammon


... so what happens if a string portion is not on the index you set but it is further down?, it would result in a erroneus correct output.
Or does it compare AT the index for only the length defined by the last value?,


Memcmp does indeed compare at the exact position you specify. It is "memory compare" not "string scan".

It compares two blocks of memory (in my example, one was a string literal) and either they exactly match, for the length you specify, or not.
http://www.gammon.com.au/electronics

cbrandy

Thanks guys!
I could use this script to have a simmilare function to left(),right() ...
Just use xxxx.length(), and then you could play with the string as you like too.

So thanks guys :)

Go Up