9

I have a String variable and I want to extract the three substrings separeted by ; to three string variables.

String application_command = "{10,12; 4,5; 2}";

I cannot use substring method because this string can be like any of the following or similar patterns also.

String application_command = "{10,12,13,9,1; 4,5; 2}"

String application_command = "{7; 1,2,14; 1}"

The only thing that is common in these patterns is there are three sections separated by ;.

Any insight is much appreciated. Thank you

3 Answers 3

30

I think you need a split-string-into-string-array function with a custom separator character.

There are already several sources on the web and at stackoverflow (e.g. Split String into String array).

// https://stackoverflow.com/questions/9072320/split-string-into-string-array
String getValue(String data, char separator, int index)
{
  int found = 0;
  int strIndex[] = {0, -1};
  int maxIndex = data.length()-1;

  for(int i=0; i<=maxIndex && found<=index; i++){
    if(data.charAt(i)==separator || i==maxIndex){
        found++;
        strIndex[0] = strIndex[1]+1;
        strIndex[1] = (i == maxIndex) ? i+1 : i;
    }
  }

  return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}

You can use this function as follows (with ";" as separator):

String part01 = getValue(application_command,';',0);
String part02 = getValue(application_command,';',1);
String part03 = getValue(application_command,';',2);

EDIT: correct single quotes and add semicolons in the example.

Sign up to request clarification or add additional context in comments.

4 Comments

Yes I saw the previous stackoverflow links. Your solution works with a minor change. String part01 = getValue(application_command , ';' , 0);. I got it working with your solution and this change. Thank you for the support.
You are right. Single quotes are correct for the second parameter (char) and each line must of course end with a semicolon.
I know it's an old post, but I like it, but I need a little extension for the function. How can I add to the function parameter like start_at_position to look like this: String getValue(String data, char separator, int startpos, int index) Thank you!
You can easily implement this by using string.substring(from) function. This could be done by calling the function with a substring (e.g., getValue(yourString.substring(yourStartPost), separator, index);) or by extending the function with an additional parameter (e.g., "data = data.substring (startpos);" in the first line of the function). Further details of substring are available online at the Arduino Reference page: arduino.cc/reference/en/language/variables/data-types/string/…
0

The new SafeString Arduino library (available from the library manager) provides a number of tokenizing/substring methods without the heap fragmentation of the String class

See
https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html
for a detailed tutorial

In this case your can use

#include "SafeString.h"

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

  createSafeString(appCmd, 50);  // large enought for the largest cmd
  createSafeString(token1, 20);
  createSafeString(token2, 20);
  createSafeString(token3, 20);
  appCmd = "{10,12,13,9,1; 4,5; 2}";
  size_t nextIdx = 1; //step over leading {
  nextIdx = appCmd.stoken(token1, nextIdx, ";}");
  nextIdx++; //step over delimiter
  nextIdx = appCmd.stoken(token2, nextIdx, ";}");
  nextIdx++; //step over delimiter
  nextIdx = appCmd.stoken(token3, nextIdx, ";}");
  nextIdx++; //step over delimiter
  // can trim tokens if needed e.g. token1.trim()
  Serial.println(token1);
  Serial.println(token2); 
  Serial.println(token3);
}

void loop() {
}

Also look at pfodParser which parses these types of messages { } for use by pfodApp.

Comments

0

Do not forget to call delete[] to free the memory after the use of the array, that said here is my solution:

String* split(String& v, char delimiter, int& length) {
  length = 1;
  bool found = false;

  // Figure out how many itens the array should have
  for (int i = 0; i < v.length(); i++) {
    if (v[i] == delimiter) {
      length++;
      found = true;
    }
  }

  // If the delimiter is found than create the array
  // and split the String
  if (found) {

    // Create array
    String* valores = new String[length];

    // Split the string into array
    int i = 0;
    for (int itemIndex = 0; itemIndex < length; itemIndex++) {
      for (; i < v.length(); i++) {

        if (v[i] == delimiter) {
          i++;
          break;
        }
        valores[itemIndex] += v[i];
      }
    }

    // Done, return the values
    return valores;
  }

  // No delimiter found
  return nullptr;
}

Here is an example of how to use:

void loop() {
  String test = "1,2,3,4,5";
  int qtde;

  String* t = split(test, ',', qtde);

  for (int i = 0; i < qtde; i++) {
    Serial.println(t[i]);
    delay(1000);
  }

  delete[] t;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.