Ich habe bereits Lösungsversuche mittels std::string sowie Verkettung ohne Operator und mit , versucht. Bisher jedoch ohne Erfolg. Ich vermute dass der + Operator hier als Binaryoperator interpretiert wird, komme an dieser Stelle jedoch selbstständig nichtmehr weiter.
Über Erläuterungen und Lösungen für mein Problem wäre ich sehr dankbar.
Wenn du einen vollständigen Sketch rund um deine Funktion baust dann kann man dir vermutlich auch eine grundsätzlich fehlerfreie Variante zeigen.
Besser wäre es aber, du beschreibst, was am Ende mit dem CSV genau passieren soll und vieleicht findet sich dann eine Variante die ganz ohne String Objekten auskommt.
Without seeing in which way you actually call the function it is not possible for me to see the issue.
There isn't anything 'really' wrong with the function itself, though usingikt may result in memory fragmentation at some point. What is returned is the pointer to the String object, which upon time of return still contains the data but pretty much goes out of scope straight away.
So if you do
String concatCsv = generateCsvFromCollectedData(collectedHoursPerSide); // or whatever argument you pass
or
Csv += generateCsvFromCollectedData(collectedHoursPerSide); // or whatever argument you pass
It is all good,
There a a chance though that it has not much to do with the String side of things but rather with argument you pass.
so for verification do
herzlich willkommen im Arduino-Forum.
Gut gemacht den code als Code-Section zu posten.
Trotzdem wie schon @noiasca angemerkt immerkompletten Sketch posten.
Auch dann wenn der Sketch 3000 Zeilen haben sollte.
Es ist viel besser gleich alle Infos zur Verfügung zu haben als bröckchenweise.
Mit Exception-Decoder ist das hier gemeint.
Damit kann man für einen Sourcecode herausfinden wo im Code die Exception auftritt.
Auch dafür wäre es nützlich exakt den kompletten Sketch zu haben bei dem die Exception auftritt
Das von dir gepostete Snippet liefert den folgenden Fehler zur Compiletime:
error: invalid operands of types 'const char [5]' and 'const char [2]' to binary 'operator+'
ich kann mit 100% Sicherheit sagen dass das Problem bei der Konvertierung des doubles in einen String und dessen Verkettung liegt.
Folgendermaßen funktioniert der Sketch und gibt mir wie erwartet "Hallo Welt" zurück.
Auch Exception sehe ich dann nicht.
Ich packe den Output der Methode in den Body eines Http Responses und schicke ihn an den Client. Das funktioniert auch solange ich nur Strings zurückschicke. Sobald ich versuche mit einem double zu verketten tritt die oben genannte Problematik auf.
Das ist auch keine Verkettung von zwei Strings, sondern ein undefinierter operator+ zwischen zwei const char*, bzw. einem const char[5] und einem const char[2]
Und ein + zwischen einem text ( const char*) und einem double gibt es auch nicht.
Wusstest du, dass "hello world" + 4 als Ergebnis "o world" ergibt? Das ist zwar erlaubt, aber auch keine Verkettung.
Tip: Strings kann man verketten, und vieles kann man in einen String verwandeln, indem man es an einen String- Konstruktor als Parameter übergibt.
double x = 3.4567;
String s = String(x); // "3.46"
s = s+String(x,5); // "3.463.45670"
String und const char* kann man leider verketten, aber das verwirrt dich offensichtlich nur.
Hallo,
danke für den Tipp. Wie aus meinem Ausgangspost hervorgeht habe ich die Konvertierung mittels String() schon probiert.
Hast du eine weitere Idee?
// SafeStrings are based on array of chars
// SafeStrings offer almost the same comfort as Strings
// but avoid some dis-advantages of variable-type String
// the name SafeString is PROGRAM They are safe to use
// with the alternatives "String" must not always but CAN
// eat up memory over time which will make the code crash
// with zero-terminated array of chars (c_string)
// you have to take care of boundary checking yourself
// otherwise your code will start to behave weird and this kind of bug is very hard to find
// you can read more about this here https://www.forward.com.au/pfod/ArduinoProgramming/ArduinoStrings/index.html#safestring
// and here https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/
// very basic demo-code to show how to declare a SafeString-variable
// and how to assign text to them
// as a personal convention I use the suffix "_SS" to indicate
// THIS IS A SAFESTRING-VARIABLE
// but you can name it whatever you like
#include "SafeString.h"
createSafeString(myTitle_SS, 64); // reserve 64 bytes for the SafeString-variable
createSafeString(myString_SS, 64); // reserve 64 bytes for the SafeString-variable
createSafeString(myExtraloongString_SS, 128); // reserve 128 bytes for the SafeString-variable
int myInteger = -1234;
float myFloat = -987.009;
float myFloat2 = -12345.6789;
float myFloat3 = -1234.567;
void setup() {
Serial.begin(115200);
Serial.println( F("Setup-Start") );
Serial.println();
myString_SS = F("fixed text directly assigned");
Serial.print( F(" #") ); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println(F("#") ); // trailing double-cross "#" to show where the string REALLY ends
myTitle_SS = F("content of an integer:");
myString_SS = myInteger;
Serial.println(myTitle_SS);
Serial.print( F(" #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
myTitle_SS = F("content of a float:");
myString_SS = myFloat;
Serial.println(myTitle_SS);
Serial.print( F(" #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
myTitle_SS = F("you can append more text with the +=-operator ");
myString_SS = F("text ");
myString_SS += myInteger;
myString_SS += F(" ,");
myString_SS += myFloat;
Serial.println(myTitle_SS);
Serial.print( F("result: #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
myString_SS += F(" ,");
myString_SS += myFloat2;
myString_SS += F(" ,");
myString_SS += myFloat3;
Serial.println(myTitle_SS);
Serial.print( F("result: #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
Serial.println( F(" now let's try to assign wayyyyyy too many characters 012345678900123456789001234567890012345678900123456789001234567890") );
myString_SS = "";
myString_SS += F(" now let's try to assign wayyyyyy too many characters 012345678900123456789001234567890012345678900123456789001234567890");
Serial.print( F("result: #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
Serial.println( F(" now let's try to add more and more characters at the end of the SafeString") );
myString_SS = "";
for (byte i = 10; i < 64; i++) {
myString_SS += i;
Serial.print( F("result: #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
}
Serial.println( F(" assigning a number of chars the SafeString can really hold") );
myExtraloongString_SS = F("less than 64 characters");
myString_SS = myExtraloongString_SS;
Serial.print( F("result: #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
Serial.println( F(" assigning too many chars than the SafeString can really hold") );
Serial.println( F("more than 64 characters 1234567890123456789012345678901234567890123456789012345678901234567890") );
// 10 20 30 40 50 60 70
// 1234567890123456789012345678901234567890123456789012345678901234567890
myExtraloongString_SS = F("more than 64 characters 1234567890123456789012345678901234567890123456789012345678901234567890");
myString_SS = myExtraloongString_SS;
Serial.print( F("result: #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
}
void loop() {
}
Ich verstehe das unbedingte nutzen von String sowieso nicht. Die machen mehr Probleme, als sie lösen.
Entweder gleich sprintf/snprintf oder wenigstens etwas, das sicher gegen Fragmentieren ist wie PString oder das SafeString, das StephanL38 vorschlägt.
Beide belegen keinen RAM dynamisch.