Probleme beim kürzen eines Strings

Hallöchen,
ich hab mal wieder ein Problem was ich irgendwie trotz Sucherei im Netz nicht wirklich gelöst bekomme.
Ich möchte einen GET-Request der mir in einem String vorliegt so bearbeiten das die ganzen unnützen Daten weg sind und ich die Nutzdaten auswerten kann.

Den String bekomme ich über
String req = client.readStringUntil('\r');

Ankommen sollte dann z.B.

GET /rgb/set/7d52ff HTTP/1.1

und brauchen würde ich 7d52ff (RGB-Wert) als String um den dann in die einzelnen RGB-Values zu zerlegen.

Allerdings bekomme ich beim zerlegen permanent folgenden Fehler:

conversion from 'void' to non-scalar type 'String' requested

Zerlegen würde ich mit folgendem Code:

String req = client.readStringUntil('\r');
int Laenge = req.length();
int index = Laenge - 9;
String gekuerzt = req.remove(index);

Woran liegt das? Kann mir hier jemand helfen?
Es geht im speziellen um einen ESP-12E / NodeMCU1.0

Danke schonmal. Grüsse, Jan

Hm.... aaaalsooo....

Dein Sketch ist etwas kurz geraten... da fehlt die Dfinition der Variablen, setup fehlt und loop fehlt. Allein mit den 4 Zeilen hast du noch kein Programm was etwas macht.

Die Möglichkeiten der String Klasse sind bei Arduino sehr beschränkt. Deswegen arbeiten die meisten nur mit C strings, das sind mit 0 abzuschließende char arrays.

Dazu solltest du dir die möglichen Befehle anschauen. mit strstr suchst du set/
das Ergebnis ist ein Zeiger, den + 4 ist der Anfang der gesuchten Zeichenkette.
Darin suchst du die Leerstelle, und ersetzt sie mit 0
und schon hast du in dem ersten Zeiger das gewünschte Ergebnis.

So mal hingetippt, ungetestet
char buffer[200];   200 Bytes als Puffer reservieren. Max Größe des Empfangenen: 199 Zeichen
.
.
String req = client.readStringUntil('\r');

char * zeiger=strstr(req.c_str, "set/");
zeiger += 4;
char * ende=strstr(zeiger," ");
ende=0;
Sreial.println(zeiger);

dapeace:
Woran liegt das? Kann mir hier jemand helfen?

Es liegt an dem Umstand, dass String::remove(int) keinen String (oder String&) zurückgibt.

Lies die Dokumentation/Definition der String Library (k.A. wo die sich für ESPs befindet).

void setup() {
  Serial.begin(115200);
  String req = "0987654321\n\r";
  int Laenge = req.length();
  int index = Laenge - 9;
  req.remove(index);
  String gekuerzt = req;
  Serial.print(F("gekuerzt = '"));
  Serial.print(gekuerzt);
  Serial.println(F("'"));
}

void loop() {}
gekuerzt = '098'

getesteter Code:

String req = "GET /rgb/set/7d52ff HTTP/1.1";

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

void loop() {
  char buffer[200];                    //200 Bytes als Puffer reservieren. Max Größe des Empfangenen: 199 Zeichen
  char * anfang = buffer;              // anfang zeigt auf die Startadresse dea Arrays

  strcpy(buffer, req.c_str());
  char * zeiger = strstr(buffer, "set/"); //zeiger zeigt auf das s
  zeiger += 4;                            //zeiger zeigt auf 4 Zeichen weiter rechts, das sit das erste Zeichen des gesuchten
  char * ende = strstr(zeiger, " HTTP");  // ende zeigt auf die Leerstelle nach dem gesuchten
  buffer[ende - anfang] = 0;              // ermitteln, an welcher Stelle das Array beendet werden soll und 0 reinsetzen.

  Serial.println(zeiger);

  while (1); // anhalten, damit man es lesen kann
}

dapeace:
Allerdings bekomme ich beim zerlegen permanent folgenden Fehler:

conversion from 'void' to non-scalar type 'String' requested

Ja, zum Parsen und Zerlegen von Strings müßte man natürlich schon so zwei bis drei Zeilen Code unfallfrei geradeaus programmieren können.

Ich habe Dir mal ein kleines Beispielprogramm gemacht:

void setup() 
{

  Serial.begin(9600);
  String request="GET /rgb/set/7d52ff HTTP/1.1\r";
  char* substr=strstr(request.c_str(),"HTTP/1.1\r")-7; // Substring lokalisieren
  int red, green,blue;
 sscanf(substr,"%02x%02x%02x%02x",&red,&green,&blue); // Substring in Farbwerte zerlegen
 Serial.println("Scanned RGB values:");
 Serial.print("red:\t"); Serial.println(red);
Serial.print("green:\t"); Serial.println(green);
Serial.print("blue:\t"); Serial.println(blue);


}

void loop() {
  
}

Das Beispielprogramm macht folgendes, alles in der setup-Funktion:

  • Serielle Schnittstelle auf 9600 Baud initialisieren
  • String als Textkonstante zuweisen
  • gesuchte Werte im String lokalisieren
  • RGB-Werte in Integerwerte umwandeln und auf Serial ausgeben

Wenn Du nach dem Programmstart den seriellen Monitor öffnest, sollten die Werte angezeigt werden.

Falls Du es anders brauchst, z.B. als eigenständige Funktion mit dem String als Funktionsparameter, gib Bescheid, das wäre nur eine minimale Änderung.

Wenn Du Fragen zum Code des Beispielprogramms hast, einfach Deine Frage hier posten.

Um auf deinen ursprünglichen Ansatz zurückzukommen (beim ESP8266 ist der Einsatz der String Klasse nicht ganz so schlimm):

  String req = "GET /rgb/set/7d52ff HTTP/1.1";
int Laenge = req.length();
uint32_t index = Laenge - 9;
req.remove(index);
req.remove(0,13);
Serial.println(req);

Tut wass du wolltest, wenn der request wirklich IMMER das gleiche Format hat. Bzw. vor dem Auswerten mit prüfen, ob es dieser RGB Request ist

Ich würde die Verwendung blockierender Funktionen wie readStringUntil vermeiden,
zumindestens auf normalen Arduinos.

Vor dem Verkürzen eines Strings sollte man testen, ob er überhaupt lang genug ist.

Danke für die zahlreichen Beiträge.
Das ganze funktioniert jetzt.
Super Sache!

Grüsse, Jan

zu readStrungUntil: in diesem Fall, wo die Daten von einem Client kommen, kann man das machen, weil der ja Pakete sendet und somit ganze Zeilen am Stück.
Bei seriellem Einlesen sollte man darauf verzichten und eine gute Einleseroutine nehmen, die nicht blockiert.