Go Down

Topic: Split string to array (Read 217 times) previous topic - next topic

abin2paul

I want split this string to arrays
.. how to program kindly help me .


String msg;

msg = "1,2,3,4,5"

I want to seperate 1 2 3 4 5 to 5 arrays..
Ary[1]= 1
Ary[2]=2.... Like this

Deva_Rishi

the most obvious is just like this
Code: [Select]
String msg;

msg = "1,2,3,4,5"
uint8_t Ary[5];
uint8_t i=0, j=0;
while ( j<msg.length()) {
  if (msg.charAt(j)==',') {
    i++;
  }
  else {
    Ary[i]=Ary[i]*10;
    if ((msg.charAt(j)<'0') || (msg.charAt(j)>'9')) {
      Ary[i]=0;
    }
    else {
       Ary[i]=Ary[i]+(msg.charAt(j)-'0');
    }
  }
  j++;
}
(no compile test done, may contain typos..) and we start counting at Ary[0].
To 'Correct' you have to be Correct. (and not be condescending..)

GolamMostafa

#2
May 26, 2019, 11:03 am Last Edit: May 26, 2019, 11:06 am by GolamMostafa
(no compile test done, may contain typos..) and we start counting at Ary[0].
Works well!

Code: [Select]
String msg = "1,2,3,4,5";
uint8_t Ary[5];
uint8_t i = 0, j = 0;

void setup()
{
  Serial.begin(9600);
  while ( j < msg.length())
  {
    if (msg.charAt(j) == ',')
    {
      i++;
    }
    else
    {
      Ary[i] = Ary[i] * 10;
      if ((msg.charAt(j) < '0') || (msg.charAt(j) > '9'))
      {
        Ary[i] = 0;
      }
      else
      {
        Ary[i] = Ary[i] + (msg.charAt(j) - '0');
      }
    }
    j++;
  }
  for (int i = 0; i < 5; i++)
  {
    Serial.print(Ary[i]); //shows 1 2 3 4 5
    Serial.print(' ');
  }
}

void loop()
{

}

J-M-L

#3
May 26, 2019, 11:06 am Last Edit: May 26, 2019, 11:12 am by J-M-L
ideally don't use the String class and stick to cString (null terminated char arrays)
there are C libraries you can use to do many things on those defined in stdlib.h and string.h.

Here is an example using strtok() and atol()
Code: [Select]
char msg[] = "1,20,300,4000,50000";

void setup()
{
  Serial.begin(115200);
  Serial.print(F("Parsing String: "));
  Serial.println(msg);
  char* ptr = strtok(msg, ",");
  byte i = 0;
  Serial.println(F("index\ttext\tNumeric Value"));
  while (ptr) {
    Serial.print(i);
    Serial.print(F("\t\""));
    Serial.print(ptr); // this is the ASCII text we want to transform into an integer
    Serial.print(F("\"\t"));
    Serial.println(atol(ptr)); // atol(ptr) will be your long int you could store in your array at position i. atol() info at http://www.cplusplus.com/reference/cstdlib/atol
    ptr = strtok(NULL, ",");
    i++;
  }
}

void loop() {}


You'll see in the console (set at 115200 bauds)
Parsing String: 1,20,300,4000,50000
index      text          Numeric Value
0          "1"           1
1          "20"          20
2          "300"         300
3          "4000"        4000
4          "50000"       50000



PS: careful for the examples given above by other posters, the use of type uint8_t Ary[5];will limit number representation between 0 and 255. The parsing code does not detect any error  and so if you have 1000 you'll overflow and won't get the right representation and if the number starts with a negative sign character it won't work either. If your array contains only small positive numbers fitting in a byte, then you are fine.

My code uses a library function to parse an long int, it can be positive or negative. Of course that code will fail if the input is not a number representation or does not fit in an unsigned long.
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

GolamMostafa

#4
May 26, 2019, 11:12 am Last Edit: May 26, 2019, 11:14 am by GolamMostafa
@ J-M-L

When OP's string "1,2,3,4,5"; is tested under your program of Post#3, the result is the following. Is it the thing that OP wants?


J-M-L

#5
May 26, 2019, 11:14 am Last Edit: May 26, 2019, 11:20 am by J-M-L
@Golam - so it works right :)

I'm not storing the result in an Array, if this is your point. I don't feel I've to explain this to the OP as other posts showed how to do that and it's trivial. I'm focusing on splitting differently without using the String class (and the comment in the code shows where is the value to use in the array)

My code would work as well with "1,-2,30000,4,5" as OP did not give any constraint on the potential type of the data in the array. My code would fail with floating point numbers though.

Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

GolamMostafa

#6
May 26, 2019, 11:20 am Last Edit: May 26, 2019, 11:23 am by GolamMostafa
so it works right :)
Your works work in fantastic ways; but, the OP wants an integer type destination array in which the ASCII coded tokens/elements of the source array would be saved. Unfortunately, there is no declaration of destination array in your sketch.  :)

J-M-L

#7
May 26, 2019, 11:23 am Last Edit: May 26, 2019, 11:28 am by J-M-L
the OP wants an integer type destination array in which the ASCII coded tokens of the source array would be saved. Unfortunately, there is no declaration of destination array in your sketch.  :)
read again what I wrote above. this is by design.
Goal here is to teach, not hand over a full solution. so I left some work for the OP to do.
OP will hopefully connect the dots and create an array of the relevant type to store the info.


Note that neither in my code nor in the code provided by @Deva_Rishi we met the original ask which is to start the array at index 1 instead of 0...

That's also something I had hoped the OP would get by seing the index explicitly starting at 0 in the output of my code.


PS/ OP Never said he wanted an integer type destination array. Just an array. Type was unspecified
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

GolamMostafa

#8
May 26, 2019, 11:44 am Last Edit: May 26, 2019, 12:46 pm by GolamMostafa
@OP

Another version (static) of solution to your problem (valid only when the source array elements are: 0 to 9):
Code: [Select]
char msg[] = "1,2,3,4,5";  //{0x31, 0x32, 0x33, 0x34. 0x35, 0x00}
byte Ary[5];  //destination array

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  for (int i=0; i<sizeof(msg); i = i+2)  //i = i+2 skips the commas without doing parsing
  {
    byte x = msg[i];    //x = 0x31
    x = x - '0';        //x = 0x31 - 0x30 = 01
    Ary[i] = x;         //Ary[0] = 01 = 1
    Serial.print(Ary[i], DEC);  //array elements are printed
    Serial.print(' ');    //insert space between prints
  }
  Serial.println();
  delay(1000); //test interval
}




J-M-L

Yes transforming based on ASCII code is a possibility too

(Sample code like this is Best done in setup as repeating in loop brings clutter in the console IMHO - but no big deal)
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Deva_Rishi

Quote
PS: careful for the examples given above by other posters,
One should always try and understand the code that is 'given' Of course the limit of the variable size is always there and depends on the array declaration. Error checking is always marginal since all the c-string function also return '0' if a non numerical value has been found. The OP wanted a conversion from 'String', we know it's possible issues, (being possible fragmentation of dynamic memory over time) But that was the request, i don't know if it is a result of an external function, if so then using c-string it would need to be converted into that first for any of the c-string code to work.
To 'Correct' you have to be Correct. (and not be condescending..)

J-M-L

#11
May 26, 2019, 06:15 pm Last Edit: May 26, 2019, 06:16 pm by J-M-L
Sure not saying your answer was not right, it was doing the job

I offered an alternative not using the String class.

For error checking one could use strtol() in the parsing.
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Go Up