I'm parsing char arrays from the serial bus and copying their contents into global arrays for handling into other functions. I'm noticing odd behavior when I use strcpy()
and strtok()
repeatedly. With the Arduino Mega, can repeated calls to strcpy
corrupt the memory address?
This is for a low-level instrument, having the Arduino act as the local microcontroller taking-in commands thru serial. I've done a few different ways of initializing the global arrays, including;
//char testDate = "YYmmDD"; //failed
//char testDate[6] = "";
//char testDate[6] = "YYmmDD";
//char testDate[6] = {'Y', 'Y', 'm', 'm', 'D', 'D'};
//char testTime = "HHMMSS"; //failed
//char testTime[6] = "";
//char testTime[6] = "HHMMSS";
//char testTime[6] = {'H', 'H', 'M', 'M', 'S', 'S'};
//char logfile[24] = "BATCH_YYmmDD_HHMMSS$.txt"; // 20 + 4, exact size
//char logfile[24] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
//char testDate[6] = ""; // Null
//char testTime[6] = ""; // Null
char testDate[6] = {'Y', 'Y', 'm', 'm', 'D', 'D'};
char testTime[6] = {'H', 'H', 'M', 'M', 'S', 'S'}; // is appending?
char logfile[24] = ""; // Null
The demo code, in it's simplest form;
#include <String.h>
char gva_logfile[24] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
char gva_testDate[6] = {'Y', 'Y', 'm', 'm', 'D', 'D'}; // is appending?
char gva_testTime[6] = {'H', 'H', 'M', 'M', 'S', 'S'};
char lva_testDate[6];
//String y = "BATCH|190117;151442$";
//int lan = y.length(); // should be 20
char x[20] = "BATCH|190117;151442$";
int lan = strlen(x);
//y.toCharArray(x, lan);
//strcpy(x, y);
//y.toCharArray(x, 20);
//strcpy(x, "BATCH|190117;151442$");
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.print("<");
for(int i=0; i<6; i++){
Serial.print(gva_testDate[i]); // works
//Serial.print(gva_testTime[i]); // works
}
Serial.println(">");
}
void loop() {
// put your main code here, to run repeatedly:
char tele[6] = {' ', ' ', ' ', ' ', ' ', ' '};
while(1){
char flarb[lan];
strcpy(flarb, x);
//Serial.println(flarb);
if(strstr(flarb, "BATCH|")){
char * strtokIndx;
strtokIndx = strtok(x, "|");
//strcpy(tele, strtokIndx); // did nothing?
strtokIndx = strtok(NULL, ";");
strcpy(gva_testDate, strtokIndx); // missing?
Serial.println(gva_testDate); // Not missing
for(int i=0; i<6; i++){
lva_testDate[i] = gva_testDate[i];
}
strtokIndx = strtok(NULL, "$");
strcpy(gva_testTime, strtokIndx); // is fine...
Serial.println(gva_testDate); // MISSING
Serial.println(lva_testDate);
if(strstr(gva_testDate, "YYmmDD")!=NULL || strstr(gva_testTime, "HHMMSS")!=NULL){
//if((gva_testDate == "YYmmDD") || (gva_testTime == "HHMMSS")){
char io[28]; // 16 + 2*6
sprintf(io, "063 ERROR: %s,%s", gva_testDate, gva_testTime);
//logArdData(io);
Serial.print("<");
Serial.print(io);
Serial.println(">");
Serial.flush();
}
//else if((strstr(gva_testDate, "YYmmDD") && strstr(gva_testTime, "HHMMSS"))==NULL){
else if((strstr(gva_testDate, "YYmmDD")==NULL && strstr(gva_testTime, "HHMMSS")==NULL)){
//else if((gva_testDate != "YYmmDD") && (gva_testTime != "HHMMSS")){
char io[26]; // 14 + 2*6
//sendArdData(gva_testDate); // is combinined?
//sendArdData(gva_testTime); // still itself
sprintf(io, "Assigned %s,%s", gva_testDate, gva_testTime); // is combining testDate and testTime, then printing testTime?
Serial.print("<");
Serial.print(io);
Serial.println(">");
//sendArdData(io);
//logArdData(io);
Serial.flush();
}
}
}
}
When I try to re-print the stored value of gva_testDate
after assigning gva_testTime
, somehow gva_testDate
has become NULL
instead of 190117
. I expected that gva_testDate
would retain its newly-assigned value, however this does not appear to be the case.
The C++ Reference pages for strcpy()
http://www.cplusplus.com/reference/cstring/strcpy/?kw=strcpy and strtok()
http://www.cplusplus.com/reference/cstring/strtok/ do not make mention of memory-corruption issues/warnings, so I would not expect repeated calls to be modifying the original string x
or the parsed char arrays gva_testDate
& gva_testTime
.