Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: Parsing and comparing strings on Teensy 3.2: different behaviour from gcc?

  1. #1
    Junior Member
    Join Date
    May 2019
    Posts
    9

    Parsing and comparing strings on Teensy 3.2: different behaviour from gcc?

    I am trying to parse a simple string, print the result of the parsing via serial.println, and trigger a function on the basis of the received command. I wrote the code below, which perfectly works in c. However, the behaviour of the same code on the arduino IDE is completely different and I really can't figure out why.

    Code:
    #include <string.h>
    
    void rcv_msg(char *rcv_msg) {
      
      char *all_tokens[2]; 
      int i = 0;
    
      all_tokens[i] = strtok(rcv_msg, "{,}");
      while (all_tokens[i] != NULL) {
        all_tokens[++i] = strtok(NULL, "{,}");
      }
    
      char *command = all_tokens[0]; 
      char *value = all_tokens[1];
    
      
      /*
      //These printls do not work, they are ignored, why?
      Serial.println("all_tokens[0]: ");
      Serial.println(all_tokens[0]);
      Serial.println("all_tokens[1]: ");
      Serial.println(all_tokens[1]);
      */
    
      if (strcmp(command,"message_1") == 0 && strcmp(value,"1") == 0) {
    
        Serial.println("message 1: ");
        Serial.println(command);
        Serial.println(value);
        Serial.println(" ");
        
      }
      
      if (strcmp(command,"message_2") == 0 && strcmp(value,"0") == 0) {
    
        Serial.println("message 2: ");
        Serial.println(command);
        Serial.println(value);
        Serial.println(" ");
        
      }
    }
    
    
    
    void setup() {
      
        Serial.begin(115200);
    }
    
    void loop() {
       
        char msg1[] = "{message_1,1}";
        char msg2[] = "{message_2,0}";
    
        Serial.println("Send msg1: ");
        rcv_msg(msg1); 
        delay(5000);
     
        Serial.println("Send msg2: ");
        rcv_msg(msg2); 
        delay(5000);    
    }
    This code gives the following output on the serial monitor, which is wrong:

    Send msg2:
    message 2:
    message_2
    {message_2,0}

    Send msg1:
    message 2:
    message_1
    {message_2,0}

    Send msg2:
    message 2:
    message_2
    {message_2,0}

    Send msg1:
    message 2:
    message_1
    {message_2,0}


    Firstly, I don't understand why at the beginning, message 2 is printed before message 1, although message 1 was sent first. Second it is not clear to me the comparison done with strcmp is always returning the message 2.


    More importantly, why running the same code in c has instead the correct output?


    The c code (which is perfectly working is this:
    Code:
    #include <string.h>
    #include <stdio.h>
    
    
    void rcv_msg(char *rcv_msg) {
        
        char *all_tokens[2]; //NOTE: the message is composed by 2 tokens: command and value
        int i = 0;
        
    
        all_tokens[i] = strtok(rcv_msg, "{, }");
        while (all_tokens[i] != NULL) {
            all_tokens[++i] = strtok(NULL, "{, }");
        }
        
        printf("all_tokens[0] : %s \n", all_tokens[0]);
        printf("all_tokens[1] : %s \n", all_tokens[1]);
        
        char *command = all_tokens[0];
        char *value = all_tokens[1];
        
        printf("command : %s \n", command);
        printf("value : %s \n", value);
        
        
    
        if (strcmp(command,"motor1_pattern1") == 0 && strcmp(value,"1") == 0) {
            printf("activating command : %s %s \n\n\n", command, value);
        }
        
        if (strcmp(command,"motor1_pattern2") == 0 && strcmp(value,"0") == 0) {
            printf("activating command : %s %s \n\n\n", command, value);
        }
    }
    
    
    
    int main() {
        
        char msg1[] = "{message_1, 1}";
        char msg2[] = "{message_2, 0}";
        
        rcv_msg(msg1);
        rcv_msg(msg2);
    
    }

  2. #2
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,086
    add while(!Serial); after Serial.begin(115200);

  3. #3
    Junior Member
    Join Date
    May 2019
    Posts
    9
    Emm I spot the error... I was accessing all_tokens[2], which is wring given the fact that that array is only long 2.

  4. #4
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,086
    I modified you sketch just a bit. It works for optimization Smallest or Fast but misbehaves for Faster and Fastest ???
    Code:
    #include <string.h>
    
    void rcv_msg(char *rcv_msg) {
    
      char *all_tokens[2];
      int i = 0;
    
      all_tokens[i] = strtok(rcv_msg, "{,}");
      while (all_tokens[i] != NULL) {
        all_tokens[++i] = strtok(NULL, "{,}");
      }
      //  Serial.println(i);
    
      char *command = all_tokens[0];
      char *value = all_tokens[1];
    
      //These printls do not work, they are ignored, why?
      Serial.print("all_tokens[0]: ");
      Serial.println(all_tokens[0]);
      Serial.print("all_tokens[1]: ");
      Serial.println(all_tokens[1]);
    
      if (strcmp(command, "message_1") == 0 && strcmp(value, "1") == 0) {
        Serial.print("message 1: ");
        Serial.print(command);
        Serial.print(" ");
        Serial.println(value);
      }
    
      if (strcmp(command, "message_2") == 0 && strcmp(value, "0") == 0) {
        Serial.print("message 2: ");
        Serial.print(command);
        Serial.print(" ");
        Serial.println(value);
      }
      Serial.println();
    }
    
    
    
    void setup() {
    
      Serial.begin(115200);
      while (!Serial);
    }
    
    void loop() {
    
      char msg1[] = "{message_1,1}";
      char msg2[] = "{message_2,0}";
    
      Serial.print("Send : ");
      Serial.println(msg1);
      rcv_msg(msg1);
      delay(5000);
    
      Serial.print("Send : ");
      Serial.println(msg2);
      rcv_msg(msg2);
      delay(5000);
    }
    However, if you uncomment the Serial.println(i), sketch works for Faster and Fastest too ????

    strange.

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,038
    @manitou - that is strange - I had to try it - and without sending '\n' the parse printing is messed up - active Teensy was the beta - but same result with FASTER is BAD and FAST is GOOD.

    Instead of println() I did ' Serial.print("---"); ' - and the "---" did not appear either without the println.

    It seems the 2nd string is losing the NULL terminate - this fails the same too:
    Code:
      Serial.printf( "all_tokens[0]: %s\n", all_tokens[0]); 
      Serial.printf( "all_tokens[1]: %s\n", all_tokens[1]);
    EDIT: It isn't just printing the '\n' - it takes the reference to (i) !

    This to Serial2 works as well :: Serial2.println(i);

    BUT THAT is just a HACK - the problem as @frodojedi indicated this array is too small to exit properly! This needs [3] elements!

    char *all_tokens[3];
    Last edited by defragster; 05-25-2019 at 07:11 PM.

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,038
    Code works nicely like this:
    Code:
    #include <string.h>
    
    void rcv_msg(char *rcv_msg) {
    	char *all_tokens[3];
    	int i = 0;
    
    	all_tokens[i] = strtok(rcv_msg, "{,}");
    	while (all_tokens[i] != NULL) {
    		all_tokens[++i] = strtok(NULL, "{,}");
    	}
    
    	char *command = all_tokens[0];
    	char *value = all_tokens[1];
    
    	Serial.print("all_tokens[0]: ");
    	Serial.println(all_tokens[0]);
    	Serial.print("all_tokens[1]: ");
    	Serial.println(all_tokens[1]);
    
    	if (strcmp(command, "message_1") == 0 && strcmp(value, "1") == 0) {
    		Serial.print("message 1: ");
    		Serial.print(command);
    		Serial.print(" ");
    		Serial.println(value);
    	}
    
    	if (strcmp(command, "message_2") == 0 && strcmp(value, "0") == 0) {
    		Serial.print("message 2: ");
    		Serial.print(command);
    		Serial.print(" ");
    		Serial.println(value);
    	}
    	Serial.println();
    }
    
    
    
    void setup() {
    
    	Serial.begin(115200);
    	while (!Serial);
    	Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
    }
    
    void loop() {
    
    	char msg1[] = "{message_1,1}";
    	char msg2[] = "{message_2,0}";
    
    	Serial.print("Send : ");
    	Serial.println(msg1);
    	rcv_msg(msg1);
    	delay(5000);
    
    	Serial.print("Send : ");
    	Serial.println(msg2);
    	rcv_msg(msg2);
    	delay(5000);
    }
    T:\tCode\FORUM\TokenParse\TokenParse.ino May 25 2019 12:13:07
    Send : {message_1,1}
    all_tokens[0]: message_1
    all_tokens[1]: 1
    message 1: message_1 1

    Send : {message_2,0}
    all_tokens[0]: message_2
    all_tokens[1]: 0
    message 2: message_2 0

  7. #7
    Senior Member
    Join Date
    May 2017
    Posts
    208
    Code:
      while (all_tokens[i] != NULL) {
        all_tokens[++i] = strtok(NULL, "{,}");   //  char msg1[] = "{message_1,1}";
      }
    There are 3 tokens in the test string( msg1[] ), open bracket, comma, close bracket. The while loop does not terminate after two iterations. And the array also stores the NULL case. I count a total of 4 array elements.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •