Langen String in Abschnitte zerlegen

Hallo,

ich möchte einen Langen String zerlegen, der nach diesem Muster aussieht:

payload =("101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116;201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216;301,302,303,304,305,306,98,308,309,310,311,312,313,314,315,316;401,402,403,404,405,406,98,408,409,410,411,412,413,414,415,416;");

Es sind immer 16 Werte, die eigentlich zwischen 0 und 255 varieren. Hier habe ich sie in Hundertergruppen unterteil um besser debuggen zu können.

Der Code sieht folgendermaßen aus

int payload_length = 5;
while (payload_length > 4) {


  int mustereinwert;
  for (int musterwert = 0; musterwert < 16; musterwert++) {
    mustereinwert = payload.substring(0, payload.indexOf(',')).toInt(); payload = payload.substring(payload.indexOf(',') + 1);
    USE_SERIAL.print(musterwert); USE_SERIAL.print(". Wert: "); USE_SERIAL.println(mustereinwert);
  }


  payload_length = payload.substring(payload.indexOf(',') + 1).length();
  USE_SERIAL.println("-");
}



}

Die Ausgabe funktioniert beim ersten Block, aber verschiebt sich dann jeweils immer um eine Stelle.
Was könnte ich denn hier noch ändern?

  1. Wert: 101
  2. Wert: 102
  3. Wert: 103
  4. Wert: 104
  5. Wert: 105
  6. Wert: 106
  7. Wert: 107
  8. Wert: 108
  9. Wert: 109
  10. Wert: 110
  11. Wert: 111
  12. Wert: 112
  13. Wert: 113
  14. Wert: 114
  15. Wert: 115
  16. Wert: 116
  1. Wert: 202
  2. Wert: 203
  3. Wert: 204
  4. Wert: 205
  5. Wert: 206
  6. Wert: 207
  7. Wert: 208
  8. Wert: 209
  9. Wert: 210
  10. Wert: 211
  11. Wert: 212
  12. Wert: 213
  13. Wert: 214
  14. Wert: 215
  15. Wert: 216
  16. Wert: 302
  1. Wert: 303
  2. Wert: 304
  3. Wert: 305
  4. Wert: 306
  5. Wert: 98
  6. Wert: 308
  7. Wert: 309
  8. Wert: 310
  9. Wert: 311
  10. Wert: 312
  11. Wert: 313
  12. Wert: 314
  13. Wert: 315
  14. Wert: 316
  15. Wert: 402
  16. Wert: 403
  1. Wert: 404
  2. Wert: 405
  3. Wert: 406
  4. Wert: 98
  5. Wert: 408
  6. Wert: 409
  7. Wert: 410
  8. Wert: 411
  9. Wert: 412
  10. Wert: 413
  11. Wert: 414
  12. Wert: 415
  13. Wert: 416
  14. Wert: 416
  15. Wert: 416
  16. Wert: 416

Nimm statt eines String Objekts ein char array, oder zur Not die Methode c_str um an den Text innerhalb deines String Objekts zu kommen.

Den kannst du bequem mit strtok zerlegen. Entweder gleich in Einzelwerte, oder erstmal in sechzehnerBlöcke, indem du nur ';' als Trenner zulässt, und diese dann jeweils in Einzelwerte.

Eigentlich müsste es auch mit deinem .substring und .indexOf Kram gehen, aber das ist mir persönlich zu kompliziert.

Das eigentliche Problem ist übrigens, dass bei dir "115,116;201,202" aus den drei Teilen "115", "116;201", "202" besteht, die sich wunderbar in die Zahlen 115, 116, 202 wandeln lassen. :wink:

In den Daten gibt es als Trennzeichen Komma und Semikolon, Du fragst aber nur nach ','.

@michael_x warst schneller :slight_smile:

michael_x:
oder zur Not die Methode c_str um an den Text innerhalb deines String Objekts zu kommen.

Das geht gerade mit strtok() nicht, da c_str() einen const char* liefert und strtok den string in situ verändern will. Das interne Arrays des Objekts durch externe Funktion ändern zu lassen wäre auch sehr schlecht. Man könnte per Gewalt das const weg-casten, aber da sollte man schon genau wissen was man tut.

da c_str() einen const char* liefert

Stimmt, da hast du recht.

Diese Warnung aktiv zu missachten, hätte ich zumindest erwähnen sollen ...

Bei String::toCharArray() sollte einem klar sein dass man eine zusätzliche Kopie erstellt, bei String::substring() aber eigentlich auch.

Also lieber gleich erst gar kein String Objekt verwenden.
Oder erst nach ';' suchen und das Zwischenergebnis nach ',' splitten. Und hoffen, dass der RAM reicht :wink:

Wobei man direkt halt erst mal keinen Zugriff hat:

String test = "12,34";
const char* test_c = test.c_str();
char* ptr = strtok(test_c, ";");

Liefert:

error: invalid conversion from 'const char*' to 'char*' [-fpermissive]

Der gleiche Fehler kommt natürlich wenn man versucht den Rückwert in einen nicht-const Zeiger zu schreiben. Ohne const-cast (was man nicht tun sollte), wird das also nichts.

Also ich saß jetzt wie lange daran und habe es mit dem strtok nicht hinbekommen.
Habe es jetzt so gelöst, vielleicht ein bisschen umständlich, aber es funktioniert endlich

Vielleicht für jemand anderes noch hilfreich

void setup() {
  Serial.begin(115200);
  delay(100);
}
int laengenachfolgend = 1;



String  myString = "101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116;201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216;301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316;401,402,403,404,405,406,98,408,409,410,411,412,413,414,415,416;";


void loop() {



  int i = 1;
  int index_0 = 0;
  int index_var = 0;
  int index_var_a = 0;
  while (laengenachfolgend > 0 ) {
    //i++;
    index_0 = i + index_var;
    int Index1 = myString.indexOf(',', index_0);
    int Index2 = myString.indexOf(',', Index1 + i);
    int Index3 = myString.indexOf(',', Index2 + i);
    int Index4 = myString.indexOf(',', Index3 + i);
    int Index5 = myString.indexOf(',', Index4 + i);
    int Index6 = myString.indexOf(',', Index5 + i);
    int Index7 = myString.indexOf(',', Index6 + i);
    int Index8 = myString.indexOf(',', Index7 + i);
    int Index9 = myString.indexOf(',', Index8 + i);
    int Index10 = myString.indexOf(',', Index9 + i);
    int Index11 = myString.indexOf(',', Index10 + i);
    int Index12 = myString.indexOf(',', Index11 + i);
    int Index13 = myString.indexOf(',', Index12 + i);
    int Index14 = myString.indexOf(',', Index13 + i);
    int Index15 = myString.indexOf(',', Index14 + i);
    int Index16 = myString.indexOf(';', Index15 + i);

    int Index17 = myString.indexOf(',', Index16 + i);
    index_var = Index15;

    String wert_0 = myString.substring(index_var_a, Index1);
    String wert_1 = myString.substring(Index1 + 1, Index2);
    String wert_2 = myString.substring(Index2 + 1, Index3);
    String wert_3 = myString.substring(Index3 + 1, Index4);
    String wert_4 = myString.substring(Index4 + 1, Index5);
    String wert_5 = myString.substring(Index5 + 1, Index6);
    String wert_6 = myString.substring(Index6 + 1, Index7);
    String wert_7 = myString.substring(Index7 + 1, Index8);
    String wert_8 = myString.substring(Index8 + 1, Index9);
    String wert_9 = myString.substring(Index9 + 1, Index10);
    String wert_10 = myString.substring(Index10 + 1, Index11);
    String wert_11 = myString.substring(Index11 + 1, Index12);
    String wert_12 = myString.substring(Index12 + 1, Index13);
    String wert_13 = myString.substring(Index13 + 1, Index14);
    String wert_14 = myString.substring(Index14 + 1, Index15);
    String wert_15 = myString.substring(Index15 + 1, Index16);

    String wert_16 = myString.substring(Index16 + 1, Index17);

    index_var_a = Index16 + 1;
    //
    Serial.println(wert_0);
    Serial.println(wert_1);
    Serial.println(wert_2);
    Serial.println(wert_3);
    Serial.println(wert_4);
    Serial.println(wert_5);
    Serial.println(wert_6);
    Serial.println(wert_7);
    Serial.println(wert_8);
    Serial.println(wert_9);
    Serial.println(wert_10);
    Serial.println(wert_11);
    Serial.println(wert_12);
    Serial.println(wert_13);
    Serial.println(wert_14);
    Serial.println(wert_15);
    Serial.println("");
    //Serial.println(wert_16);
    laengenachfolgend = wert_16.length();

    /*Serial.println(laengenachfolgend);
      Serial.println(Index16);
      Serial.println(Index17);*/
    Serial.println("-");


    delay(1000);
  }





  delay(10000);

}