FINDing within strings

Hey guys,

Hoping someone can help me out with finding a sequence of predefined characters within a string.

I have a string that is built from characters coming over the serial port. I want to find if a certain predefined string of characters exists within than longer string.

There is a c++ function for this - find - std::basic_string<CharT,Traits,Allocator>::find - cppreference.com - I just can't work out how to use it properly within arduino world. I THINK it may have something to do with declaring my string using the char type (as in the arduino string reference page) - but that's just a guess at this stage.

Does anyone have any info or can point me in the right direction please?

Thanks

Alex

There are strings and there are strings and there are Strings. Which string do you have?

String is not a built-in type in C++, so the "string" you have is either an instance of a class, and we need to know which one, or it is "an array of characters that is NULL-terminated".

How you find a substring depends on what you have.

I THINK it may have something to do with declaring my string using the char type (as in the arduino string reference page)

This doesn't make sense. The string reference page talks about the string class that is now built into 0019.

this - find -

The avr-gcc compilers and, in particular, the Arduino distribution do not directly support any of the C++ STL (Standard Template Library) classes. No std::string stuff no std::vector stuff. The limited resources of chips like the ATMega328p restricts the things that we can do. Bummer.

If you are using a version earlier than arduino-0019, I suggest that you stick with C-style "strings" and their standard C library functions. I looked briefly at the downloadable String class when I first started with Arduino a couple of months ago and I really, really (really) didn't like what I saw. The first two things that I tried didn't work, and there are numerous references to memory leaks in threads in this forum. Bottom line: Lots of bugs, and it's just downright butt-ugly (in my opinion). Maybe some of the ugliness that I perceived was due to someone's attempt to "fix" some of the worst of the bugs---I just don't know.

However...

For arduino-0019 there is a "String" class (note the upper-case 'S') that has some of the convenience (but not all of the functionality) of the standard C++ library std::string class. Browse the source code and look at examples supplied with arduino-0019 to see whether you like it. It certainly seems cleaner to me than the older "unofficial" String class, but I haven't fully evaluated it to see if I might want to use it. Maybe you can find something there that meets your needs.

If you can't find something that's already there, then maybe you can add a new member function to the class (it's open source after all) to get the standard C library function strstr(const char *haystack, const char *needle) to do the work of finding whether a substring is part of a given string. Or, you can just pretend it's C and not C++ and use C-style "strings" and their standard library functions (which are supported by avr-gcc).

Regards,

Dave

In the below thread (the string comparison one) I posted some code that can find "woohoo" in a string. It is for arduino 0018, as it is reported that Wstring is broken in 0019.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1284102010/0

Dude, that is awesome, thanks heaps. Worked perfectly - just added my own series of strings that I am looking for.

Still trying to learn exactly HOW it works, but it does!

Thanks again

You could roll your own, like this:

/*
      http://alexanderbrevig.com
      Search haystack for the needle
*/
bool has(char *haystack, char *needle)
{
      int compareOffset = 0;
      //iterate through the zero terminated string heystack
      while(*haystack) {
            if (*haystack == *needle) { //we might have found a match
                  compareOffset = 0; //start at the current location in haystack
                  //see if the string from that location matches the needle
                  while (haystack[compareOffset] == needle[compareOffset]) {
                        compareOffset++;
                        if (needle[compareOffset]=='\0') {
                              return true; //we have reached the end of needle and everything matched
                        }
                  }
            }
            haystack++; //increment the location in the string (the pointer)
      }
      return false; //no match was found
}

Use like this:

void setp() {
  Serial.begin(9600);
  if (has("test string","t s")) { Serial.println("'test string' contains 't s'"); }
  if (!has("test string","s t")) { Serial.println("'test string' does not contain 's t'"); }
}