Parsing problem with strtok - teensy 3.2

Status
Not open for further replies.

efiocco

Member
Dear people,

I'm struggling with a parsing problem, actually I'm sending strings through the serial usb (each 100ms), it works fine for a while (1 minute or so) and then suddently it stops.
I've tried everything that came to my mind without success...

Here's a simplified code:



void setup(void) {
Serial.begin(115200);
Serial.setTimeout(5);
}

#define STR_SIZE 40

void loop(void) {

char input[STR_SIZE + 1];

while (Serial.available() > 0) {

Serial.readBytes(input, STR_SIZE);
// Serial.println(input);
char* p = strtok(input, " ");
char* p1 = strdup(p);
p = strtok(NULL," ");
char* p2 = strdup(p);
p = strtok(NULL," ");
char* p3 = strdup(p);
p = strtok(NULL," ");
char* p4 = strdup(p);

Serial.print (p1);
Serial.print (p2);
Serial.print (p3);
Serial.println(p4);

}

}



Hope to have some help... thanks!
E
 
This is less elegant but it works:


if (Serial.available() > 0) {

String s1 = Serial.readStringUntil(' ');
Serial.read();
String s2 = Serial.readStringUntil(' ');
Serial.read();
String s3 = Serial.readStringUntil(' ');
Serial.read();
String s4 = Serial.readStringUntil('\0');

char a1[8];
s1.toCharArray(a1, 8);
char a2[8];
s2.toCharArray(a2, 8);
char a3[8];
s3.toCharArray(a3, 8);
char a4[8];
s4.toCharArray(a4, 8);
}
 
From a general C perspective, I'd guess you're running out of memory by strdup()ing a lot, but not free()ing them. I'm not sure what Arduino does for memory management, but it can't magically be creating more memory whenever it runs out!

[edit to add:] There's no point to strdup()ing in your code anyway...strtok() modifies the buffer containing the line, but p1, p2, p3 and p4 can take the results of strtok() directly, and you can print them out as you're doing.
 
hello, thanks for your reply, I thought that I have to strdup to store the tokens somewhere cause my p is modified each iteration... but I'm completely a beginner in C, I'll give it a try!
[edit]: I want to display the substrings to different oled displays so I can't delete them... should I free the p1, p2, ecc instead??
Thanks again
 
Last edited:
I don't have one of those displays, so I don't know how it works. But my guess is, once you send the string over with print() or println(), it keeps whatever information it needs (and you can throw away whatever you have).

strtok() does modify the string, but all it's doing is putting a '\0' between the individual words. It doesn't erase or change anything else. So you could probably do:

char input[STR_SIZE + 1];

while (Serial.available() > 0) {

Serial.readBytes(input, STR_SIZE);
// Serial.println(input);
char* p1 = strtok(input, " ");
char* p2 = strtok(NULL, " ");
char* p3 = strtok(NULL, " ");
char* p4 = strtok(NULL, " ");

Serial.print (p1);
Serial.print (p2);
Serial.print (p3);
Serial.println(p4);

// Since you didn't do strdup(), you don't have to free() anything.
}


Actually, you could probably combine the strtok() with the Serial.print() and not even bother with p1, p2, p3, p4:

char input[STR_SIZE + 1];

while (Serial.available() > 0) {

Serial.readBytes(input, STR_SIZE);
// Serial.println(input);

Serial.print (strtok(input, ""));
Serial.print (strtok(NULL, " "));
Serial.print (strtok(NULL, " "));
Serial.println(strtok(NULL, " "));

// Since you didn't do strdup(), you don't have to free() anything.
}
 
Last edited:
Status
Not open for further replies.
Back
Top