strtok

I'm traing to use the strtok function to break a POST string and use the parts of the string. It breaks the string but when I try to compare what I recived it don't work and how can I stop the loop?

 char *entrada ="nome=Guilherme&senha=123&submit=Enviar";
 char *dados[6];

void setup() {
  
  pinMode(13, OUTPUT);
  pinMode(49, OUTPUT);
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // send an intro:

}

void loop() {
  // get any incoming bytes:

  char *string="";
  char *aux="";
  char *aux2="Guilherme";
  //if (Serial.available() > 0) {
          
          string = strtok(entrada,"=&");
          int i=0;
          while (string != NULL) {  

            string = strtok(NULL, "=&");
            dados[i] = string;   
            
            Serial.write(dados[i]);
            Serial.println();
            delay(2000);
            i++; 
            if (string == aux2) {
              
              digitalWrite(49,HIGH);
              delay(10000);
              digitalWrite(49, LOW);  
            }
          }  
          
          aux = dados[0];
          
          if (aux == aux2) {
            
            digitalWrite(49,HIGH);
            delay(10000);
            digitalWrite(49, LOW);    
          
        }else {
            digitalWrite(13,HIGH);
            delay(2000);
            digitalWrite(13, LOW);  
        }
    //}
}
            if (string == aux2) {

That is not how you compare strings. Try strcmp().

  char *string="";
  char *aux="";
  char *aux2="Guilherme";

char * is a pointer to type char.

char *string = ""; // initializes an empty string array with 1 char member which is 0 // and sets the pointer named string to the address of it

you can just make a pointer and use it in strtok.

char *string; // string is initialized to NULL

if (aux == aux2) { // compares the addresses of the 2 pointers. TRUE if they are the same.

Here is the string.h library of AVR GCC: http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html

Bookmark this page; AVR Libc Home Page. http://www.nongnu.org/avr-libc/user-manual/modules.html

            string = strtok(NULL, "=&");
            dados[i] = string;

At the end of the loop containing this code, ALL the elements of the dados array are going to point to the same memory location. That memory location will actually be NULL, because the while loop only ends when string is NULL.

This is NOT how to copy data from a string by parsing it.

Probably the best way to understand strtok() is through the strtok source code.

if I use it without the while? it break the string the way I want in the first loop the problem is on the next loops, there's a way to stop the loop?

 char *entrada ="nome=Guilherme&senha=123&submit=Enviar";
 char *dados[5];

void setup() {
  
  pinMode(13, OUTPUT);
  pinMode(49, OUTPUT);
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // send an intro:

}

void loop() {
  // get any incoming bytes:

  char *string;

  //if (Serial.available() > 0) {
          
          string = strtok(entrada,"=&");
          dados[0] = string;
          Serial.write(dados[0]);
          Serial.println();
          delay(1000);
          
          string = strtok(NULL, "=&");
          dados[1] = string;
          Serial.write(dados[1]);
          Serial.println();
          delay(1000);
          
          string = strtok(NULL, "=&");
          dados[2] = string;
          Serial.write(dados[2]);
          Serial.println();
          delay(1000);
          
          string = strtok(NULL, "=&");
          dados[3] = string;
          Serial.write(dados[3]);
          Serial.println();
          delay(1000);
          
          string = strtok(NULL, "=&");
          dados[4] = string;
          Serial.write(dados[4]);
          Serial.println();
          delay(1000);
          
          string = strtok(NULL, "=&");
          dados[5] = string;
          Serial.write(dados[5]);
          Serial.println();
          delay(1000);
          
           
          
        if (((strcmp(dados[1], "Guilherme")) && (strcmp(dados[3], "123"))) ==0 ) {
            
            digitalWrite(49,HIGH);
            delay(10000);
            digitalWrite(49, LOW);    
          }
        
    //}
}

if I use it without the while? it break the string the way I want in the first loop the problem is on the next loops, there's a way to stop the loop?

Stop which loop? If the string is tokenized correctly the first time, and the string is reset, refilled, and tokenized again, it WILL be tokenized correctly the next time. If it isn't, it's because you are not resetting the string or refilling it correctly.

  char *string;

  //if (Serial.available() > 0) {
          
          string = strtok(entrada,"=&");
          dados[0] = string;
          Serial.write(dados[0]);
          Serial.println();
          delay(1000);

dados[ 0 ] now points to the same place string does.

          string = strtok(NULL, "=&");
          dados[1] = string;
          Serial.write(dados[1]);
          Serial.println();
          delay(1000);

dados[ 1 ] now points to the same place string does, which is the same place that dados[ 0 ] points.

          string = strtok(NULL, "=&");
          dados[2] = string;
          Serial.write(dados[2]);
          Serial.println();
          delay(1000);

dados[ 0 ], dados[ 1 ], and dados[ 2 ] now all point to the same place.

Since this is probably NOT what you want, it's clear that ASSIGNING the pointer to dados[ n ] is NOT what you want to do. Have a look at strdup(). Don't forget that the allocated memory (allocated by strdup()) needs to be freed at some point, or you'll run out.

guimas: it break the string the way I want in the first loop the problem is on the next loops, there's a way to stop the loop?

I'm not sure what 'the problem' refers to. When you call strtok() on a buffer, it modifies the content of the buffer to terminate each token that it returns. Since you don't reset the buffer content subsequently, all you're parsing next time is the first token, which we already know doesn't include the token separator. I'd expect that to process the tokens on the first pass, and not subsequently. I have no idea whether this is what you intend to happen since you haven't said what you want to happen.

Note that you should check the return value for strtok() before using it - the code sample you posted assumes that all the calls to strtok() return a valid token.

The code you use here to compare the received string looks wrong:

if (((strcmp(dados[1], "Guilherme")) && (strcmp(dados[3], "123"))) ==0 )

Also note that strcmp() returns zero if the two arguments match - in the code above you check the second return value correctly, but not the first.

Guimas,
I’ve noticed a few people trying to tokenize an input stream over the past few days. So i wrote this little sketch to give an example of how to use strtok() in the Arduino environment. There are some important differences from the example on cplusplus.com so I thought an example might help you get your data tokenized.

Let me know if this gets you pointed in the right direction.

/* strtok() Arduino example for a string contained in 
   the source code.  

   based on the reference example at: 
   http://www.cplusplus.com/reference/cstring/strtok/

   Zac Staples. July, 2013.
*/

void setup() {
	Serial.begin(9600);
	char str[] = "{label,4,8,9}";
	char* p;
	Serial.print("Example of splitting a string into tokens: ");
	Serial.print("The input string is: '");
	Serial.print(str);
	Serial.println("'");

	p = strtok(str, "{,}");	//2nd argument is a char[] of delimiters
	while (p != '\0') {	//not equal to NULL
		Serial.println(p);
		p = strtok('\0', "{,}");	//expects NULL for string on subsequent calls
	}
}

void loop() {
	delay(250);
}