AnsiString-Umwandlung in double, Prüfen auf Zahlen
-
Hallo
Ja mit einem Update auf einer neuere Builder-Version. StrToFloatDef ist afaik ab Builder 6 dabei.
FloatToStrDef aber ist natürlich nirgends dabei, da alle floats ohne Fehler in einen String umgewandelt werden können.bis bald
akari
-
akari schrieb:
FloatToStrDef aber ist natürlich nirgends dabei, da alle floats ohne Fehler in einen String umgewandelt werden können.
warum zeigt er mir dann den Fehler in der Zeile des Aufrufs an? Dort wandel ich ja einen Float in einen String. Der Debugger meint "" ist kein gültiger double -Wert.
Bei Delphi Exceptions stoppen muss ich im Debugger auch deaktivieren damit es funktioniert.
-
rudpower schrieb:
Der Debugger meint "" ist kein gültiger double -Wert.
Dann hast du wohl einen leeren String übergeben.
-
Hallo
Der Fehler wird zwar in dieser Zeile angezeigt, aber wird nicht von FloatToStr ausgelöst (warum auch, ob ein leerer String nun ein gültiger double-Wert ist oder nicht, interessiert diese Funktion nicht). Sondern der Fehler wird von dem StrToFloat ausgelöst, das in der Funktion ErfasseVolumen verwendet wird. Der Debugger zeigt nur gerne Fehler eine Aufrufebene höher an als tatsächlich ausgelöst.
Trenne mal die Zeile so auf und du wirst sehen, das der Fehler in der ersten Zeile ausgelöst wird, und nicht in der zweitendouble x = F_Messgeraet->GetMessgeraet()->ErfasseVolumen(); F_HO->E_AnzeigeVolumen->Text = FloatToStr(x);
bis bald
akari
-
ah ok, das leuchtet ein. Vielen Dank.
Was ich vielleicht noch ändern will ist, dass return 0 eigentlich nicht so gut ist. Dann könnt man denken, dass der Messwert 0 ist und weiss als Benutzer gar nicht, dass die Verbindung zum Messgerät getrennt wurde. Einen String kann ich aber nicht zurückgeben, da ja die Funktion als Rückgabetyp einen double hat. Kann man das vll doch irgendwie machen? Sonst müsst ich alle meine Funktionen ändern und den Rückgabetyp auf AnsiString ändern. Ausserdem werden die Daten dann in einer Klasse und in einem Vektor gespeichert und dort wird ein double verlangt.
-
Hallo
Bei float/double ist das kein Problem, denn dafür gibts NaN (Not a Number).
Am besten definierst du dir eine globale Konstante, die du anstelle der 0 verwendest, um Fehler anzugeben#include <limits> const double nan = std::numeric_limits<double>::quiet_NaN(); ... double func() { // Wenn Fehler, nan zurückgeben return nan; } ... double x = func(); if (x == nan) { // Fehlerbehandlung }
bis bald
akari
-
habs mal so versucht:
double c_Messgeraet::ErfasseVolumen() { if (m_connect) { char rec[50] = {0}; unsigned char send[] = {0x16}; while(m_port.ReceiveData(rec,1)>0); // Buffer leeren m_port.SendData(send,1); m_port.ReceiveData(rec,50); try {return StrToFloat(AnsiString(rec).SubString(4,9).Trim());} catch(...) { m_connect = false; return 0; } } else return 0; }
Aufruf:
if (F_Messgeraet->GetMessgeraet()->GetConnect()) F_HO->E_AnzeigeVolumen->Text = FloatToStr(F_Messgeraet->GetMessgeraet()->ErfasseVolumen()); else F_HO->E_AnzeigeVolumen->Text = "getrennt";
das sieht so schon mal ganz gut aus. Der Aufruf steht in einem Thread und wird ständig aktualisiert. So kann man immer den aktuellen Status sehen. Leider kann ich es jetzt nicht mehr richtig testen, da ich das Messgerät bis morgen früh abgeben musste. Aber so könnte es funktionieren denk ich.
Edit: Deinen Beitrag hab ich zu spät gelesen:)
-
aber das kannt ich auch noch nicht. Danke für den Tipp. Der Aufruf meiner Funktion ist leider in einer anderen Form und somit ist nan nicht bekannt.
Was hältst du von meiner Methode. Wenn das morgen dann funktioniert werd ich das mal ausprobieren.
-
Hallo
rudpower schrieb:
Was hältst du von meiner Methode. Wenn das morgen dann funktioniert werd ich das mal ausprobieren.
Scheint in Ordnung zu sein (habs aber nur mal überflogen).
aber das kannt ich auch noch nicht. Danke für den Tipp. Der Aufruf meiner Funktion ist leider in einer anderen Form und somit ist nan nicht bekannt.
Für solche unit-übergreifenden Konstanten kannst du ruhig einen neuen, eigenen Header aufmachen, in dem nur diese Konstanten drinne stehen (mit notwendigen includes und include-guards natürlich). Diesen Konstanten-Header includest du dann in jeder Unit in der du es brauchst.
bis bald
akari
-
Das hier
double x = func(); if (x == nan) { // Fehlerbehandlung }
sollte nicht funktionieren, da ein Vergleich von NaN-Werten immer false ergibt. Das kann man aber nutzen.
double x = func(); if (x != x) // falls x NaN ist ergibt das true { // Fehlerbehandlung }