Problem with parsing a simple string.....( Solved #7)

I have a simple function to parse an incoming string via serial. The incoming string has a format of :

<X,5,2018,09,06,22,15,00> ( for trial I am directly entering this in the Arduino monitor)

The < and > are start and end markers.
The 5 is a interval value in second.
Rest of the string is YYYY,MM,DD,HH,MM,SS

When i try to print the result i always get zero for all places. What am i doing wrong ?

// ********************************

void parseLVmessage() {

  char interval[4], yearVal[5], monthVal[3], dayVal[3];
  char hourVal[3], minuteVal[3], secondVal[3];
  char *parsedMsg;

  int intervalInt, yearInt, monthInt, dayInt, hourInt, minuteInt, secondInt;

  parsedMsg = strtok(msgFromLVapp, ",");    // Discard the first X character

  parsedMsg = strtok(NULL, ",");
  strcpy( interval, parsedMsg);
  interval[4] ='\0';
  intervalInt = atoi(interval);

  parsedMsg = strtok(NULL, ",");
  strcpy( yearVal, parsedMsg);
  yearVal[5] ='\0';
  yearInt = atoi(yearVal);

  parsedMsg = strtok(NULL, ",");
  strcpy( monthVal, parsedMsg);
  monthVal[3]='\0';
  monthInt = atoi(monthVal);

  parsedMsg = strtok(NULL, ",");
  strcpy( dayVal, parsedMsg);
  dayVal[3]='\0';
  dayInt = atoi(dayVal);

  parsedMsg = strtok(NULL, ",");
  strcpy( hourVal, parsedMsg);
  hourVal[3]='\0';
  hourInt = atoi(hourVal);

  parsedMsg = strtok(NULL, ",");
  strcpy( minuteVal, parsedMsg);
  minuteVal[3]='\0';
  minuteInt = atoi(minuteVal);

  parsedMsg = strtok(NULL, ",");
  strcpy( secondVal, parsedMsg);
  secondVal[3]='\0';
  secondInt = atoi(secondVal);

  Serial.print(intervalInt);
  Serial.print(" : ");
  Serial.print(yearInt);
  Serial.print(" : ");
  Serial.print(monthInt);
  Serial.print(" : ");
  Serial.print(dayInt);
  Serial.print(" : ");
  Serial.print(hourInt);
  Serial.print(" : ");
  Serial.print(minuteInt);
  Serial.print(" : ");
  Serial.println(secondInt);

  EEPROM.put(epromAddress, intervalInt);
  loggingInterval = intervalInt; 
  rtc.adjust(DateTime(yearInt, monthInt, dayInt, hourInt, minuteInt, secondInt));

}
  strcpy( interval, parsedMsg);

You really should be using strncpy(), to assure that you are not writing beyond the end of the destination array.

  interval[4] ='\0';

Your 4 element array does NOT have a position 4. You just crapped on memory not owned by that array.

strcpy() already NULL terminated the destination array in the proper place.

You are writing beyond the end of all your other arrays, too.

Ardubit:
I have a simple function to parse an incoming string via serial. The incoming string has a format of :

Please post your complete program.

There is a parse example in Serial Input Basics

...R

You don't have to copy the substrings at all and you could use sscanf if you have enough Flash free.

char testData[] = "<X,5,2018,09,06,22,15,00>";

void setup() {
  Serial.begin(250000);
  sscanfMessage(testData);
  parseMessage(testData);
}
void loop() {}


void sscanfMessage(char* msgFromLVapp) {
  int intervalInt, yearInt, monthInt, dayInt, hourInt, minuteInt, secondInt;

  sscanf(msgFromLVapp, "<X,%d,%d,%d,%d,%d,%d,%d>",
         &intervalInt, &yearInt, &monthInt, &dayInt, &hourInt, &minuteInt, &secondInt);

  Serial.print(intervalInt);
  Serial.print(" : ");
  Serial.print(yearInt);
  Serial.print(" : ");
  Serial.print(monthInt);
  Serial.print(" : ");
  Serial.print(dayInt);
  Serial.print(" : ");
  Serial.print(hourInt);
  Serial.print(" : ");
  Serial.print(minuteInt);
  Serial.print(" : ");
  Serial.println(secondInt);
}

void parseMessage(char* msgFromLVapp) {
  char *parsedMsg;
  int intervalInt, yearInt, monthInt, dayInt, hourInt, minuteInt, secondInt;

  strtok(msgFromLVapp, ",");
  parsedMsg = strtok(nullptr, ",");
  intervalInt = atoi(parsedMsg);
  parsedMsg = strtok(nullptr, ",");
  yearInt = atoi(parsedMsg);
  parsedMsg = strtok(nullptr, ",");
  monthInt = atoi(parsedMsg);
  parsedMsg = strtok(nullptr, ",");
  dayInt = atoi(parsedMsg);
  parsedMsg = strtok(nullptr, ",");
  hourInt = atoi(parsedMsg);
  parsedMsg = strtok(nullptr, ",");
  minuteInt = atoi(parsedMsg);
  parsedMsg = strtok(nullptr, ",");
  secondInt = atoi(parsedMsg);

  Serial.print(intervalInt);
  Serial.print(" : ");
  Serial.print(yearInt);
  Serial.print(" : ");
  Serial.print(monthInt);
  Serial.print(" : ");
  Serial.print(dayInt);
  Serial.print(" : ");
  Serial.print(hourInt);
  Serial.print(" : ");
  Serial.print(minuteInt);
  Serial.print(" : ");
  Serial.println(secondInt);
}
5 : 2018 : 9 : 6 : 22 : 15 : 0
5 : 2018 : 9 : 6 : 22 : 15 : 0

PaulS:

  strcpy( interval, parsedMsg);

You really should be using strncpy(), to assure that you are not writing beyond the end of the destination array.

  interval[4] ='\0';

Your 4 element array does NOT have a position 4. You just crapped on memory not owned by that array.

strcpy() already NULL terminated the destination array in the proper place.

You are writing beyond the end of all your other arrays, too.

Yes that null terminating Index was a mistake. Tried to run the code after correcting that and yet got only zeros. Maybe now I will try the strncpy() to see if it helps.

Thanks

Robin2:
Please post your complete program.

There is a parse example in Serial Input Basics

...R

I know the part of posting the full code. But in this particular case this code snippet is complete in itself as I am yet to reach the stage of getting the string via serial and just trying out by feeding the string as i mentioned in the Arduino IDE directly. Once i have this going as expected, i can merge into the main code.

Yes i have read your Serial Input Basics

@Whandhall

Thanks for the different option ... unfortunately i am already on the edge of the available memory on the 32U4 MCU and was unable to fit it in. Possibly i can use this as a handy reference in future. Looks good.

PaulS:

  strcpy( interval, parsedMsg);

You really should be using strncpy(), to assure that you are not writing beyond the end of the destination array.

  interval[4] ='\0';

Your 4 element array does NOT have a position 4. You just crapped on memory not owned by that array.

strcpy() already NULL terminated the destination array in the proper place.

You are writing beyond the end of all your other arrays, too.

Done. Changing the strcpy() to strncpy() did the trick and of course removed the null terminating statement.

Thanks.

Ardubit:
Done. Changing the strcpy() to strncpy() did the trick and of course removed the null terminating statement.

Again, you don't have to use a str(n)cpy() at all.

I included that example in my post also.

Ardubit:
Yes i have read your Serial Input Basics

I suspected that but as you had not posted the full program or told us I did not want to assume it.

...R