I am trying to receive a string via serial containing a standard format for date code. "Time: 00:00:00 MM/DD/YYYY"
I can get this string into an array of char called buf[33];
Then I want to copy the second string containg the time using strtok() delimited by space. Then I want to copy the tkn (char *) returned by strtok() into ntpDate[8]. This method works for getting the date string into ntpDate[10] but for ntpDate I get an empty array or at least an array with a white space character only. I also Serial.println'ed the tkn and it appears to be correct before and after I use strcpy. Relevant code below. Any help is appreciated.
String recieved = s;
char buf[33];
char ntpClock[8];
char ntpDate[10];
recieved.toCharArray(buf,33);
char * tkn;
//seperate into strings for clock and date
tkn = strtok(buf, " ");
tkn = strtok(NULL, " ");
strcpy(ntpClock,tkn); //WHERE MY ISSUE IS
tkn = strtok(NULL, " ");
strcpy(ntpDate,tkn); //WORKS AS EXPECTED
tkn = strtok(NULL, " ");
I tried making it larger and smaller to force an error if I could. Nothing happens. Its like a singlenul character is going from tkn to ntpTime but when tkn to ntpDate it works fine.
To be honest if you know the structure of the buffer, and that numbers Are exactly where you expect them then you know the index and could just grab them directly from the array.
If you are happy to overwrite the contents of buf, if you don't need the whole thing again, then it's even easier. Put string terminators into buf, and use it in place.
And alternative way of doing this is with a union. People used to do this kind of thing all the time with COBOL data sections. It's handy if you are working with a lot of variables all having the same fixed format.
Note that in C++ this is against the standard but supported by most compilers. If you initialize the union with a buf, then accessing the parsed structure is implementation dépendant and undefined behavior.
The union is only as big as necessary to hold its largest data member. The other data members are allocated in the same bytes as part of that largest member. The details of that allocation are implementation-defined, and it's undefined behavior to read from the member of the union that wasn't most recently written. Many compilers implement, as a non-standard language extension, the ability to read inactive members of a union.
With the union approach don't forget to put the scrap values to '\0' to be able to use the arrays as C strings though which would then make the structure the latest member to be written to and thus legit to access, but with no standard guarantee that the former data will be still arranged the way you expected it to be.