String an Semikolon splitten und Inhalt wieder ausgeben?

Hallo zusammen. Ich lese einen String ("command") über verschiedene Quellen ein. In diesem Fall als Beispiel über die Serielle Schnittstelle. Dabei ist der String erstmal beliebig und veränderlich.

Nun möchte ich über einen String mehrere Infos zur gleichen Zeit verarbeiten. Dies werde ich über Trennzeichen realisieren. Sprich ich schreibe Anweisungen hintereinander und trenne sie über ein Semikolon. BSP: ERSTE_ANWEISUNG;ZWEITE_ANWEISUNG;DRITTE_ANWEISUNG

Dabei weiß ich vorher genau, dass ich immer nur z.B. 3 Anweisungen übertrage. Das heisst ich möchte jede Anweisung in einem eigenen String stehen haben. Somit wird der Inhalt der Variable command auf drei weitere Variablen aufgeteilt: ANW1, ANW2, ANW3

Wie mache ich das möglichst einfach?

String command;

void setup() {
  Serial.begin(9600);
  Serial.println("Programm wurde gestartet");
}


void loop() { 
read_konsole();
}

void read_konsole(){
  if (Serial.available() > 0){ 

    command = Serial.readString();
    handle();
        
   }
}

void handle() {

  if (command=="ANW1"){
      Serial.println("Anweisung I");
    } else if (command=="ANW2"){
      Serial.println("Anweisung I");
    } else if (command=="ANW3"){
      Serial.println("Anweisung I");
    } else {
      Serial.print("Unbekannte Eingabe: "); Serial.println(command);
    }
    
}

hi,

klar geht das, aber:

warum schickt eine maschine, die nicht lesen kann, eine lesbare anweisung an eine zweite maschine, die auch nicht lesen kann?

gibt es mehr als 256 anweisungen? wenn nicht, schick drei bytes, da brauchst Du nichts mehr auseinanderzudividieren.

wenn mehr als 256, schick drei doppelbytes, mehr als 65536 wirst Du ja kaum brauchen.

denk' immer einfach, die maschine tut das auch...

gruß stefan

magie004: ... Wie mache ich das möglichst einfach?

Ob das für Deinen Bedarf das Beste oder Einfachste ist, weiß ich nicht.

Mir fällt bei Deiner Frage jedenfalls das Stichwort struct ein. In der Referenz kommt das allerdings nicht vor (wenn’s jemand weiß: warum?)

Wenn Du Deine Befehle in Form von Werten kodieren kannst, kannst Du das zum Beispiel so machen:

// struct-test

struct bla
{
  int eins;
  int zwei;
  int drei;
} befehle;


void setup()
{
  befehle.eins=1;
  befehle.zwei=2;
  befehle.drei=3;

  Serial.begin(9600);
}

void loop()
{
  Serial.println(befehle.eins);
  Serial.println(befehle.zwei);
  Serial.println(befehle.drei);
  while(1) {};
}

Gruß

Gregor

Ich muss einmal bremsen. Meine Anforderungen haben schon einen Sinn. Der übertragene String übermittelt eine echte Information und nicht nur ein Signal. Natürlich könnte ich ein Byte übertragen, aber darum soll es hier gar nicht gehen. Habt ihr dennoch eine Lösung, wie ich den String splitte?

Grüße, Max

strtok

magie004: Meine Anforderungen haben schon einen Sinn. Habt ihr dennoch eine Lösung, wie ich den String splitte?

Äh ... mich würde interessieren, worin der Sinn besteht, wenn es mit den vorgeschlagenen Dingen nicht geht.

Ansonsten: Beschäftige Dich mit char-Arrays :-) Man kann zum Beispiel gucken, ob und wo ein „Sonderzeichen“ steht. Dann kann man das char-Array entsprechend „behandeln“.

Ist diese Antwort nützlicher? Wenn nicht: warum?

Gruß

Gregor

Ich schließe mich combie an und stimme für strtok

ElEspanol: Ich schließe mich combie an und stimme für strtok

Dem stimme ich auch zu und damit der TO nicht erst lange suchen muss, hier die Beschreibung wie es geht: http://www.cplusplus.com/reference/cstring/strtok/

Oder hier ein weiteres Beispiel in Post #5, wenn es in int gewandelt werden soll, sonnst einfach "atoi" weglassen. http://forum.arduino.cc/index.php?topic=431774.5 Und passende Variablen einsetzen.

gregorss: Äh ... mich würde interessieren, worin der Sinn besteht, wenn es mit den vorgeschlagenen Dingen nicht geht.

Gern, hier der Sinn. Angenommen ich übermittle Informationen zum schalten eines IR-Gerätes. Dann haben wir einen Code: 0xF3XXXX eine Bitzahl, z.B. 24 und die Info welches Protokoll verwendet wird.. Diese Informationen möchte ich als String zusammensetzen und später wieder splitten.

Ich lese mich mal in die Antwort der anderen ein. Danke soweit

Ich komme leider nicht weiter. Überall werden nur Char * gesplittet. Wie splitte ich meinen eingelesenen String, wie im Code oben angefangen?

magie004: Ich komme leider nicht weiter. Überall werden nur Char * gesplittet. Wie splitte ich meinen eingelesenen String, wie im Code oben angefangen?

Dan wandle es doch in ein char array um .

magie004:
Ich komme leider nicht weiter. Überall werden nur Char * gesplittet.
Wie splitte ich meinen eingelesenen String, wie im Code oben angefangen?

Meine Güte … lies halt, was in der Referenz zum Datentyp String steht.

Vielleicht stolperst Du dabei über „c_str“, womit Du Deinen String in ein „char*“ konvertieren kannst :wink:

Gruß

Gregor

PS: Oder erwartest Du Code, den Du hirnlos kopieren kannst?!

gregorss: PS: Oder erwartest Du Code, den Du hirnlos kopieren kannst?!

Wäre ja immerhin möglich, das jemand einen solchen Code-Teil aus seinem aktuellen Projekt kopieren kann. Ein Forum lebt doch insbesondere auch als Code-Sammlung, oder? Wie hast du denn mit Programmieren angefangen?

magie004: Ein Forum lebt doch insbesondere auch als Code-Sammlung, oder?

Dass man ein Forum (auch) als Code-Sammlung sehen kann, ist okay.

magie004: Wie hast du denn mit Programmieren angefangen?

Indem ich gelesen, fremden Code abgetippt und so lange probiert habe, bis ich verstanden hatte, worum es geht.

Du postest Code, in dem Du Befehle wie „anw1“, „anw2“ benutzt, findest es anscheinend aber blöd, wenn jemand vorschlägt den Datentyp int zu verwenden. Vielleicht überlegst Du nochmal, wie Du das, was Du machen möchtest, auch einfacher anstellen könntest.

Hier im Forum ist eigentlich jeder erstmal willkommen. Aber wer sich als lernresistent und denkfaul outet, hat schlechte Karten.

Gruß

Gregor

magie004: Ich komme leider nicht weiter. Überall werden nur Char * gesplittet. Wie splitte ich meinen eingelesenen String, wie im Code oben angefangen?

Das kann man sehr einfaach beantworten: Weil die Verarbeitung von char * , wie auch das Zerlegen, um Größenordnungen einfacher ist, als sich mit Strings rumzuschlagen. Nebenbei ist es auch noch speicherschonender. Deswegen tut sich das mit Strings keiner an.

Gruß Tommy

gregorss: Hier im Forum ist eigentlich jeder erstmal willkommen. Aber wer sich als lernresistent und denkfaul outet, hat schlechte Karten.

Moral-Apostel waren schon immer sehr hilfreich. Frage mich immer, wer sich Zeit nimmt, Fragen zu kommentieren, ohne zu Lösungen beizutragen. Nicht jeder möchte Programmierer werden, sondern ist vielleicht nur daran interessiert neben dem Job ein Projekt zu realisieren, wo es im Sinne der Zweckmäßigkeit überhaupt nicht sinnvoll ist vorerst Abläufe zu verstehen, wenn es auch anders geht. Programmieren kann später jemand der sich damit auskennt und da Spaß dran hat. Jetzt weiß ich, das du keinen Code parat hast, aber dem Rest stelle ich gern am Ende meine Lösung zur verfügung, damit es schneller geht :)

Cheers

magie004:
… ohne zu Lösungen beizutragen.

Ich habe in meiner ersten Antwort auf struct und int hingewiesen. In meiner dritten Antwort haue ich Dich förmlich mit einem Hinweis auf „c_str“.

Nennst Du das wirklich „nicht zu Lösungen beitragen“?! Lass’ Dir Dein Programm von jemandem stricken, der Ahnung hat (und demzufolge wahrscheinlich Geld dafür haben möchte. Lies das hier und ersetze „Linux“ durch „Arduino“.

Gruß

Gregor

gregorss: Vielleicht stolperst Du dabei über „c_str“, womit Du Deinen String in ein „char*“ konvertieren kannst ;-)

Jein. Eher nicht. c_str() liefert einen const Zeiger auf das interne Array des String Objekts. Das taugt für einiges, aber gerade nicht für strtok(), da strtok() die Zeichenkette ändert. Und genau das lässt ein const char* nicht zu.

Am besten man liest gleich in ein char Array ein statt ein String Objekt. Ansonsten gibt es noch das alte toCharArray(), aber damit belegt man halt zusätzlich noch mal Speicher.

Weshalb hier niemand zeigt wie man String Objekte direkt splittet: weil es elendig umständlich ist

Schau in die Reference von String

Du musst Dir etwas umständliches mit indexOf() , lastIndexOf() und substring() bauen.

Gruß Tommy

Serenifly:
Jein. Eher nicht. c_str() liefert einen const Zeiger auf das interne Array des String Objekts. Das taugt für einiges, aber gerade nicht für strtok(), da strtok() die Zeichenkette ändert. Und genau das lässt ein const char* nicht zu.

Das stimmt, aber ein const char* in ein char* zu kopieren sollte für niemanden ein Problem darstellen.

Gruß

Gregor