Parsing Out a Serial Char String

I have the following char String that arrives at Serial3 on the Mega2560: acid235912311659715A

"acid" is always there, the length is always the same, but the remaining values may all change.

So I need to read just specific groups, 4th & 5th = "23" = hour

"23" = hour "59" = minutes "12" = month "31" = day "16" = year "59715" = zip "A" = id

I am not finding any straight forward ways to address individual bytes in the string.

Suggestions.

Are you getting that in a String object (bad idea) or a char buffer?

If a char buffer and always same format then

char buffer[] = "acid[color=red]23[/color]5912311659715A";

then byte hour = 10*(buffer[4]-'0')+(buffer[5]-'0');same idea for the others

If it a String object get rid of that code and use a char buffer :) (or to get started use yourBadIdeaString.c_str() to get to the buffer)

Another way to get rid of the String is:

void setup() {
  char id;
  char temp[7];
  int count;
  int data[5];
  long zip;

  Serial.begin(9600);

  char buffer[] = "acid235912311659715A";

  memset(temp, '\0', sizeof(temp));     // Clear to NULLs
  count = 0;
  for (int i = 0; i < 10; i += 2) {
    strncpy(temp, &buffer[4 + i], 2);   // Copy only 2 characters
    data[count++] = atoi(temp);         // Convert to an int and save
  }
  strncpy(temp, &buffer[14], 5);
  zip = atol(temp);                     // Copy 5 characters into a long
  id = buffer[19];                      // Then the ID
  for (int i = 0; i < 5; i++) {
    Serial.println(data[i]);
  }
  Serial.println(zip);
  Serial.println(id);
}

void loop() {
}

combover61: I have the following char String that arrives at Serial3 on the Mega2560: acid235912311659715A

"acid" is always there, the length is always the same, but the remaining values may all change.

So I need to read just specific groups, 4th & 5th = "23" = hour

"23" = hour "59" = minutes "12" = month "31" = day "16" = year "59715" = zip "A" = id

So if the hour was say.. 4 would it be written 04?

-jim lee

59718

If the time is 23:07 do you get ...2307.. or do you get ....237....

The latter would make things very complicated.

Can you change the sending program so it places delimiters between the fields - like this acid,23,59,12,31,16,59715,A

...R

why acid?

-jim lee

He said "the length is always the same " so I supposed single digits do have a 0 padding in front thus the approach suggested above will work fine

J-M-L: He said "the length is always the same " so I supposed single digits do have a 0 padding in front thus the approach suggested above will work fine

Just checking ... :)

(Measure twice and cut once)

...R

:) merry Christmas for those getting closer

JML - I am not sure of the difference between a String object (bad idea) or a char buffer? I am sending the string via WIFI from a PC to a remote device, it includes a null character at the end (\n ).

ECONJack - Thank you.

KTALL - 59718?

Robin2 - Yes it sends hour 23, minutes 7 as 2307. Yes, if it would make things easier, I can easily add delimiters between the fields.

Jim Lee - Hour 4am = 04, correct. Acid simply tacked on the beginning as a string marker, added step to make sure that string is the expected string and not some other string that I did not foresee being transmitted in my network.

... just got back from the Holidays, so looking forward to trying these things above, many thanks to the generous visitors

I was reading your post and noticed the zip code. My zip code is 59718.

combover61: Yes, if it would make things easier, I can easily add delimiters between the fields.

Have a look at the parse example in Serial Input Basics

...R

it includes a null character at the end (\n ).

‘\n’ is not a null character… it’s the line feed character… it’s represented by 0x0A in ascii, not 0x00 which is the proper way to end a string char buffer in C/C++

Text strings can be represented in two ways. you can use the String class data type, or you can make a string out of an array of type char and null-terminate it. the String object gives you some higher level interface functionality at the cost of more memory and possibly poking holes in your heap. cstring, cstdlib and cstdio string related functions are available and solve all the challenges easily though so I don’t see much value in that class.

See this for the char buffer and that page for the class

You can read also this The Evils of Arduino Strings to understand the possible challenge of the class when you have limited memory

combover61: I am sending the string via WIFI from a PC to a remote device, it includes a null character at the end (\n ).

Just to follow from Reply #13, it is quite normal for a message to end with a linefeed '\n' character and the 2nd example in my Serial Input Basics expects that.

But, as @J-M-L has said that is not a cstring terminating character and my example adds a '\0' character after it receives all the data.

...R

ALL ... than you kindly ... still struggling with the details ...

serialEvent(); if (stringComplete) { //Serial.print("WIFI 2 received: \n"); if (WIFIString.startsWith("acid")) { char buffer[16] = WIFIString[16]; byte strtime[7] = 10*(char buffer[4]-'0')+(char buffer[7]-'0'); // Get the 4 digit hour from the string. writeTime(strtime); // 2359 hour and minutes to be writeen to displays

ERROR: array must be initialized with a brace-enclosed initializer (ON LINE THAT STARTS char buffer[16]).

char buffer[16] = WIFIString[16];

On the left side you declare an array of 16 chars On the right side you access the 17th element of the array WIFIString

This does not copy the 16 chars from WIFIString into buffer

You could use strcpy or memcpy to achieve this when needed, but here why do you need that intermediary buffer? why don't you just use the content of WIFIString directly??