unten stehender Code soll meine Eigabe über BT einfach parsen und mir die entsprechende Datei im SPIFFS auf mein Terminal (Handy) holen. Klappt auch aber ich bin wohl mit String etwas durcheinander gekommen. Da die String Klasse (und auch Stream) sehr komfortabel sind nutze ich sie auch und versuche nur "by reference" zu arbeiten. Probleme mit Speicherfragmentierung hatte ich noch nie.
Hier schaue ich, ob nur "show" gesendet wurde oder "show filename" kam. Der Fehler wird sichtbar in der Ausgabe. Der dateiname dname ist am Ende mit ^@ versehen, also vermutlich nicht Null Terminiert. Ich suche das Leerzeichen und zerschneide damit den String. Den zweiten Tag übergebe ich der SPIFFS Funktion, die die Datei ausliest. Mit String Filename klappt es wo der aktuelle Dateiname global steht, mit dem zerteilten String nicht.
Im BT Terminal Programm sende ich Befehle NULL Terminiert ab, das kann man ankreuzen ob /r/n oder NULL oder was anderes.
debugln(dname) zeigt "230323.txt^@ an. Erzeugt substring keinen Null terminierten Strring?
Hab deinen Code nicht nachvollzogen, aber: ^@ könnte die Darstellung
eines \0-Zeichens durch dein Terminal sein.
Dann wäre das ja bei den anderen Strings auch so. ist es aber nicht. Ich versuche es als letzte Möglichkeit alles in ansi c umzu schreiben mit string funktionen aber das ist eben mühsamer.
War eh noch ein Fehler drin, das Root zeichen fehlte
String dname = "/" + mystring.substring(pos+1); // Hole Dateiname
Dann wäre das ja bei den anderen Strings auch so. ist es aber nicht.
Das meine ich nicht. Wenn ^@ das \0-Zeichen am Stringende sein sollte, dann dürfte es gar nicht auf dem Terminal erscheinen. Das könnte nur passieren wenn das Längenfeld in der String-Klasse nicht mit dem Inhalt des Zeichenkettenpuffers des Strings übereinstimmt. Und das deutet auf Speicherkorruption hin. Womöglich existiert der String an der Stelle, wo er ausgegeben wird, schon gar nicht mehr?
Womöglich existiert der String an der Stelle, wo
er ausgegeben wird, schon gar nicht mehr?
Wie meinst Du das? Soll ich ihn mal global volatile definieren? Nur zur Info. Hänge ich ein '\0' mit dran habe ich zweimal ^@^@ da stehen. Also hast Du wohl recht.
Ich glaube du vermischst hier "Null-Terminierte Char-Arrays" und die String-Klasse munter miteinander. Und dann gibt es auch noch einen Unterschied zwischen "string" und "String". Bei den Klassen heißt eine Null nicht automatisch Stringende.
Ich glaube du vermischst hier "Null-Terminierte Char-Arrays" und die
String-Klasse munter miteinander. Und dann gibt es auch noch einen
Unterschied zwischen "string" und "String". Bei den Klassen heißt eine
Null nicht automatisch Stringende.
Das hilft mir bei meinem Problem jetzt aber auch nicht weiter. Woher diese extra zeichen kommen? Ich benutze String seit jeher und nie gab es Probleme damit. Leider habe ich keinen echten Debugger wie beim stm32, so dass ich nicht eben ins Ram schauen kann wie es da aussieht.
Die Stringlaenge wird wohl irgendwo im private Teil des Objektes stehen,.
Ist übrigens egal ob by reference oder by value, gleiches Ergebnis.
show unsinn müsste eine fehlermeldung erzeugen, dass die Datei nicht exisiert. Tut es aber nicht, rennt er so drüber. Und der Rest hat vermutlich mit dem Terminal zu tun. String können genausogut \r\n terminiert sein. Oder eben gar nicht, wenn die Länge irgendwo steht.
1
/* Zeige das heutige File */
2
voidshowTodayFile(String*dateiname){
3
4
Stringlokal=*dateiname;
5
6
/* Datei öffnen */
7
debugln("Oeffne Datei "+lokal);
8
Filefile=SPIFFS.open(lokal);
9
if(!file){
10
debugln("showTodayFile: Failed to open "+lokal+" for reading");
solltest du angeben, dass du die Datei zum Lesen öffnen willst. Sonst
wird einfach eine Datei mit falschem Namen angelegt, und dein
Nicht ganz. Default ohne Parameter ist lesen. Und gelesen habe ich alles was drüber gibt heute, seit 10 Uhr. Sitze hier im Schlafanzug, den ganzen Tag nur Kaffee und Kippen. Ah, Berlin Entscheid auch gescheitert, sehr gut. Gibt ja noch Vernünftige dort.
substring scheint entweder fehlerhaft zu sein oder das ist ein Feature, dass da eine Null zwischenrutscht. Abgesehen davon dass ich den Punkt vergessen habe. Ich werde heute abend mal ne Kanne Kaffee bereitstellen und schreibe den ganzen Ramsch auf string Funktionen um, da weiss ich wenigstens was bei rauskommt. ChatGPT leistet da auch sehr gute Hilfe.
Ich kann mit dem Informationsgehalt von Einzeilern leider nichts anfangen. Auch wenn das in Chats so üblich ist. Ich mische gar nichts. Da rutscht eine Null rein wo keine hin gehört. Ist so!
Es sieht so aus, als ob das Problem darin besteht, dass Sie einen Pointer auf dname an die Funktion showTodayFile übergeben, obwohl dname eine lokale Variable in der if-Anweisung ist. Sobald die if-Anweisung beendet ist, wird die Variable dname außerhalb ihres Gültigkeitsbereichs fallen gelassen und ihr Speicherplatz wird möglicherweise von anderen Daten überschrieben werden. Der Pointer, der an showTodayFile übergeben wird, würde daher auf einen ungültigen Speicherbereich zeigen, was zu unvorhersehbarem Verhalten führen kann.
Um dieses Problem zu beheben, könnten Sie stattdessen eine Variable vom Typ String deklarieren und diese dann an showTodayFile übergeben, anstatt einen Pointer auf dname zu übergeben. Hier ist eine modifizierte Version des Codes:
ChatGPT sollte besser auch ein paar Tassen Kaffee trinken, wenn sich das auf den von dir gezeigten Code bezieht. Wenn du dem natürlich anderen Code gegeben hast, kann das durchaus sein.
Ich denke es liegt eher daran, dass der String, den deine HandleBT-Funktion übergeben bekommt, am Ende ein NULL enthält. Dann ist die NULL natürlich auch im Ergebnis des substring-Aufrufs vorhanden.
An deiner Stelle würde ich prüfen, woher die NULL am Ende kommt. Entweder dann an der Aufruf-Stelle ändern oder am Anfang der HandleBT-Funktion abschneiden (bzw. trimmen).
Nur so eine Frage am Rande: welche Hardware benutzt du auf beiden Seiten
Ein Smartphone und einen Esp32. Strings werden mit cr lf jetzt terminiert beim Senden. Ich teste das heite abend mal mit String Konstanten statt mit dem Terminal Programm
open in spiffs erwartet einen cstring aka. const char * path als Argument, keinen String. Wie man diesen cstring erzeugt, habe ich im post verlinkt. Der Rest ist deine Sache.
open in spiffs erwartet einen cstring aka. const char * path als
Argument, keinen String. Wie man diesen cstring erzeugt, habe ich im
post
Ich schätze wirklich jede Hilfe. Aber wenn jemand ohne jeden Nachweis falsche Behauptungen aufstellt dann winke ich auch ab. Andere schrieben es schon, spiffs ist ein Fs Objekt und das lässt String zu. Rechter Mausklick und schon sieht man das. Ich werde das alles trotzdem umschreiben ohne String. Ist zwar aufwendiger mit der stdlib aber ich weiss da genau was da passiert.
Ich denke es liegt eher daran, dass der String, den deine
HandleBT-Funktion übergeben bekommt, am Ende ein NULL enthält. Dann ist
die NULL natürlich auch im Ergebnis des substring-Aufrufs vorhanden.
sehe ich auch so. Ein String kann '\0' Zeichen enthalten.
1
Strings("test");
2
s+='\0';
3
Strings2=s.substring(2);
4
Serial.println(s2.length());
liefert Länge = 3, die 0x00 ist im String s und Substring s2 enthalten.
Hier passiert er! Ich bin es gewohnt, dass der + Overload Operator Strings nahtlos zusammen schreibt als Ascii Zeichen. Und das ist eben nicht der Fall hier.
Da die Befehle eh auf Makro Tasten liegen und feste Größen bestehen ist die Null jetzt weg. Die kommt von irgendwoher rein, vermutlich vom BT Terminal. Und Kollegen sagten mir auch dass String keinen Terminator hat, die Länge wird ständig angepasst von den Methoden, je nachdem wie der verwurstelt wird.
Und Kollegen sagten mir auch dass String keinen Terminator hat, die
Länge wird ständig angepasst von den Methoden, je nachdem wie der
verwurstelt wird.
Da hilft es, den Quellcode von WString.h und auch WString.cpp mal ernsthaft zu studieren ...