Help in Split String into Array

Hey guys,

I thought that splitting strings was easier than in fact it is. Here is my code:

String inData;
String myArray[2];

void loop() {
  inData = "";
  if (Serial.available() > -1) {
     int h=Serial.available();    
      for (int i=0;i<h;i++){
             inData += (char)Serial.read();
         }
   }

From serial, I am getting and string like: RB,35
the inData var stores the string and than it has to be split into an array like: myArray[0] = RB ; myArray[1] = 35;
So the first data is a word and the second data is a value from 0 to 255.

I had a look at this topic http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1247911854 but I don't know how to implement it in my sketch because they are using char instead of string.

thank you.

Should avoid strings... anyhow why not just skip the single string and copy straight into the array

char c_Temp[3] = { 0, 0, 0 };

c_Temp[ 0 ] = Serial.read();
c_Temp[ 1 ] = Serial.read();
Serial.read();
myArray[0] = c_Temp;
c_Temp[ 0 ] = Serial.read();
c_Temp[ 1 ] = Serial.read();
myArray[1] = c_Temp;

There is a problem with your original too, they are only copying 1 character, you need two characters per string going off your example. EDIT: can put a read and dump the ',' value when collecting data rather than removing/splitting the data later. This code wont do if the incoming strings are of variable length though.

First study char arrays, will make things more straight forward. There are also alot of character array manipulation functions available, string is not a real good choice.

One more thing - you should make sure there are enough characters in the serial buffer before doing multiple reads.

At the moment you use "if(Serial.available()>-1)". This will always be true, as it returns 0 or more. You should check to see if it is at least as great as the number of characters you want to read before you next to a check on the Serial.available.

Thank you for reply,

I tried to use your improvements, and I am getting bad values:

,1
RB

This is the code:

  if (Serial.available() > 0) {
     /*int h=Serial.available();    
        // if you are getting escape -characters try h--; here
      for (int i=0;i<h;i++){
             //inData += (char)Serial.read();  
         }*/
         char c_Temp[3] = { 0, 0, 0 };
         c_Temp[0] = Serial.read();
         c_Temp[1] = Serial.read();
         Serial.read();
         myArray[0] = c_Temp;
         c_Temp[0] = Serial.read();
         c_Temp[1] = Serial.read();
         myArray[1] = c_Temp;
   }
   Serial.println(myArray[0]);
   Serial.println(myArray[1]);

Using if(Serial.available()>0) I am losing 0 values, for example if I send value 10, I just get back 1. I don't know if you understand me.

If you are expecting a certain sequence it is better to wait for enough data rather than do stuff when anything is available.
if you need two characters per element and 1 for the delimeter ( the ',' character ) then wait until that is available.

if (Serial.available() > 0)

#define REQUIRED_DATA_LEN  5
//...
if(Serial.available() >= REQUIRED_DATA_LEN ){
  //Do Stuff.
}

After you have enough data start the copy process, maybe verify the ',' is actually an ',' character ( to kind of ensure data is valid ), if so, continue

if you are expecting a certain sequence it is better to wait for enough data rather than do stuff when anything is available.

The problem is that I don't know how long is going to be the value 'cause it may vary from 0 to 255.

And I am still having the same trouble parsing the string into array. Sorry these gets quite complicated for me.

if you are expecting binary data, 1 byte is all you need to wait for, if it is text then you need to wait for a max of 3 characters.

E.g.

255,255

your incoming data is max seven chars long, wait till available then read data into variables. While reading check for a ',' to determine when to read into the second array element.

Ok, now I understood your code and I've modified a bit but I'm still getting wrong values in the serial monitor.

Here is the code

void loop() {
  if (Serial.available() >=7) {
    char c_Temp[3] = {0,0,0};
    c_Temp[0] = Serial.read();
    c_Temp[1] = Serial.read();
    c_Temp[2] = Serial.read();
    if (c_Temp[2] = ',') {
      myArray[0] = c_Temp;
    }
    c_Temp[0] = Serial.read();
    if(c_Temp[0] !=0) {
    c_Temp[1] = Serial.read();
      if (c_Temp[1] !=0) {
        c_Temp[2] = Serial.read();
      }
     myArray[1] = c_Temp;
    } else {
     myArray[1] = 0;
    }
  Serial.println(myArray[0]);
  delay (50);
}

Serial.println prints:

R,......
B,,....
RB,....
R,....

,....
0
,....
10,....
,1,....
B,,....
RB,....
myArray[0] = c_Temp;

does not do what you probably expect. Unfortunately, it's no syntax error :wink:

Is it still defined as

  String myArray[2];

?

If you do not follow the rule "No String: they produce more trouble than help" ,
then at least think remember that c_Temp is just a char array, but without terminating 0, so you cannot use it as a string, e.g. to initialize a String object.

Is it still defined as
String myArray[2];
?

Yes it is. The problem is that I don't know how to handle the incoming data. I mean a entire word (e.g. RB) and an hole number (e.g 125) in a 2 positions char array.

The problem is that I don't know how to handle the incoming data.

Me neither.
You do not know the exact length , right ?
You know it contains two parts, separated by a comma , right ?
How do you know the end ? ( A line end, perhaps 0x0D 0x0A ) ? ( The worst case: "Well, no more characters for half a second". Don't ask for this ???)

I'd use a different approach than pYro_65: store each character as it arrives and act when a delimiter ( ',' , anything not 0..9 or A..Z , any other criteria ?) is found.
Perhaps you skip any bad characters ( space, newline, whatever) in this stage ?
Then replace the delimiter with a 0 ( or add one, if you did not store that delimiter in c_Temp yet )
and use that partial string to build your new String array element.

After a comma it builds array[0], after a different delimiter it builds array[1] , if this is what you want (?)
Your incoming data buffer c_Temp can be reset after each part was processed and just needs the size for one part, plus the '\0'.
Don't write beyond the size of c_Temp!