Splitting delimited strings with strtok_r

Hi,

I copied a basic strtok_r function from this post:

http://forum.arduino.cc/index.php/topic,41389.0.html

Here is my version which doesn't seem to work, it gets caught in the loop:

void testChar()
{
  char *str;
  char sz[] = "will,this,work,70,4";
  char *p = sz;
  while ((str = strtok_r(p, ",", &p)) != "\n") 
    {
     mySerial.println(str);
     mySerial.println("location 7");
    }
}

Can I please get some guidance on what I'm doing wrong? Am I missing a null terminator?

Subsequent calls to strtok_r have to have NULL passed as the first argument, eg.

char *p = sz;
  while ((str = strtok_r(p, ",", &p)) != "\n") 
    {
     mySerial.println(str);
     mySerial.println("location 7");
     p = NULL;
    }

And even that is dodgy because strtok changes the thing passed to it (in this case p, which points to sz, which is a literal).

This at least works once:

void testChar()
{
  char *str;
  char sz[] = "will,this,work,70,4";
  char *p = sz;
  while (str = strtok (p, ",")) 
    {
     Serial.println(str);
     p = NULL;
    }
}

void setup ()
  {
  Serial.begin (115200);
  testChar ();
  }  // end of setup

void loop () { }

No need for the re-entrant version of strtok.

You could do it with a regular expression (more powerful anyway, and it doesn’t corrupt the input string):

#include <Regexp.h>

// called for each match
void match_callback  (const char * match,          // matching string (not null-terminated)
                      const unsigned int length,   // length of matching string
                      const MatchState & ms)       // MatchState in use (to get captures)
  {
  char cap [50];   // must be large enough to hold captures
  ms.GetCapture (cap, 0);  // get first capture
  Serial.println (cap); 
  }  // end of match_callback 

char sz [] = "will,this,work,70,4";

void setup ()
  {
  Serial.begin (115200);
  MatchState ms (sz);
  ms.GlobalMatch ("([^,]+)", match_callback);
  }  // end of setup  

void loop () { }

Output:

will
this
work
70
4

Regular expression library:

http://www.gammon.com.au/forum/?id=11063

Thank you for your suggestions Nick. I found that the "\n" is the problem, it works with NULL as follows:

void testChar()
{
  char *str;
  char sz[] = "will,this,work,70,4";
  char *p = sz;
  while ((str = strtok_r(p, ",", &p)) != NULL)  // Don't use \n here it fails
    {
     mySerial.println(str);
     mySerial.println("location 7");
    }
}