Here is a small program with 3 different way of parsing "[color=blue]TRACE_IP=192.168.1.2[/color]"
char cstringToParse[25];
uint8_t ip[4];
unsigned long chrono;
void setup() {
Serial.begin(115200);
// *******************************************
// VERSION WITH strtok() and atoi()
// *******************************************
strcpy(cstringToParse, "TRACE_IP=192.168.1.2"); // to simulate receiving from wherever
chrono = micros();
char * item = strtok(cstringToParse, ".=");
uint8_t index = 0;
while (item != NULL) {
if ((*item >= '0') && (*item <= '9')) {
ip[index++] = atoi(item);
}
item = strtok(NULL, ".=");
}
chrono = micros() - chrono;
Serial.print(ip[0]); Serial.print(".");// debug
Serial.print(ip[1]); Serial.print(".");// debug
Serial.print(ip[2]); Serial.print(".");// debug
Serial.print(ip[3]);// debug
Serial.print(" executed in "); Serial.println(chrono);
// *******************************************
// *******************************************
// VERSION WITH sscanf()
// *******************************************
strcpy(cstringToParse, "TRACE_IP=192.168.1.2"); // to simulate receiving from wherever
chrono = micros();
sscanf(cstringToParse, "TRACE_IP=%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3);
chrono = micros() - chrono;
Serial.print(ip[0]); Serial.print(".");// debug
Serial.print(ip[1]); Serial.print(".");// debug
Serial.print(ip[2]); Serial.print(".");// debug
Serial.print(ip[3]);// debug
Serial.print(" executed in "); Serial.println(chrono);
// *****************************************************************
// VERSION WITH manual parsing (cf post from MarkT)
// *****************************************************************
uint8_t idx = 0;
int intval = 0 ; // temporary for building up value on the fly
byte part = 0 ; // index into ip_addr
strcpy(cstringToParse, "TRACE_IP=192.168.1.2"); // to simulate receiving from wherever
chrono = micros();
while ((cstringToParse[idx] != '=') && (cstringToParse[idx] != '\0')) idx++; // find the '='
if (cstringToParse[idx] != '\0') {
idx++ ; // skip the '='
while (true)
{
if (cstringToParse[idx] == '.' || cstringToParse[idx] == '\0') { // part separator / end of string
part++ ; // skip to next byte
if (cstringToParse[idx] == 0 || part == 4) // done if 4 parts parsed or end of string
break ;
else ip[part] = 0 ;
} else if (cstringToParse[idx] >= '0' && cstringToParse[idx] <= '9') {
ip[part] = ip[part] * 10 + (cstringToParse[idx] - '0') ; // build up value from decimal digits.
} else
break ;
idx++ ; // step to next char
}
}
chrono = micros() - chrono;
Serial.print(ip[0]); Serial.print(".");// debug
Serial.print(ip[1]); Serial.print(".");// debug
Serial.print(ip[2]); Serial.print(".");// debug
Serial.print(ip[3]);// debug
Serial.print(" executed in "); Serial.println(chrono);
}
void loop() {}
if you run it as is you'll get in the console (set at 115200 bauds)
</sub> <sub>[color=blue]192.168.1.2 executed in 84 192.168.1.2 executed in 388 192.168.1.2 executed in 32 [/color]</sub> <sub>
which is the result of the very same debug code
chrono = micros() - chrono;
Serial.print(ip[0]); Serial.print(".");// debug
Serial.print(ip[1]); Serial.print(".");// debug
Serial.print(ip[2]); Serial.print(".");// debug
Serial.print(ip[3]);// debug
Serial.print(" executed in "); Serial.println(chrono);
--> so the three versions are working and giving the right result (the IP address is detected correctly)
Now you can comment out 2 versions out of the 3 and look at memory / performance impact of each version
Version with manual parsing uses 2100 bytes of program memory and 259 bytes of RAM (I slightly adapted MarkT code from post #10 by using direct array access and removing most error testing to be comparable to the other options) and executes in ~36 microseconds
Version with strtok() and atoi() uses 2230 bytes of program memory and 265 bytes of RAM and executes in ~84 microseconds
Version with scanf() uses 3854 bytes of program memory and 281 bytes of RAM and executes in ~328 microseconds
So you clearly see that by doing things yourself you save the most for everything program memory, RAM and performance, that the C functions strtok() et atoi() will add a bit to the three and scanf() is more costly.
At the same time this comes at the expense of "code complexity", the version with sscanf() is just one line of code, definitely much faster to program and understand, the strtok() version has a few more lines and the manual version "pretty long" so what you gain in code readability / maintainability you loose somewhat in performance and memory impact
if you were to use the String class then memory impact and time performance would be even worse.
So recommendation if you are tight in program memory space and want things to go quick, then go with "manual" parsing (and add comments in the program for maintainability)