String in Float umwandeln



  • ich bekomme von einem Messgerät alle 1 Sekunde einen String, der 2 Messwerte enthält. Diese möchte ich extrahieren. Ich erhalte z.B.:
    "-1.234799131e-001 9.721627919e-001 E,AB\r\n" Wie man sieht sind in dem String auch noch Leerzeichen und Vorzeichen usw. Die Kommastelle ändert sich evtl auch noch bei der Übertragung des Messwerts. Bei bestimmten Zuständen kommt statt dem Messwert auch eine Statusmeldung.
    Nun will ich die Werte in eine Datei schreiben als Float-Wert und brauche so die 2 Messwerte.
    Ich würde nun mit SubString und if else alle Fälle versuchen abzufangen. Wie würdet ihr das machen?



  • Hallo

    Solange du sicher sein kannst, das du die Zahlen an dem Format "*e-* " erkennen kannst, ist die Weiterverarbeitung mit den String-Methoden wirklich am leichtesten. Für komplexere Formate wäre dann die Verwendung von Regulären Ausdrücken interessant.

    bis bald
    akari



  • hab mal mit SubString den ersten Wert extrahiert. Damit ich den ersten Wert mit StrToFloat umwandeln kann muss der Punkt als Dezimaloperator durch ein Komma ersetzt werden. Gibts eine Ersetzen-Funktion für Strings?



  • Ja, die gibts.
    Guck dir mal AnsiReplaceStr/AnsiReplaceText an. Ausserdem solltest du dir auch DecimalSeparator angucken, diese globale Variable enthält das Zeichen, das als Dezimalpunkt benutzt wird und von der Windows Locale Einstellung anhängt.



  • ersatzweise gibts noch "atof"...



  • AnsiReplaceStr/AnsiReplaceText gibts bei mir in der Hilfe nicht. Ich denke mal das liegt daran, dass ich mit dem Borland Builder 5 arbeite.
    Wie verwende ich den DecimalSeparator?

    hier mal mein Code:

    AnsiString s("-1.234799131E-001 9.721627919e-001 E,AB\r\n"); // als Bsp. global definiert
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    	AnsiString c = s.SubString(1, 17);
       int i = c.Pos(".");
       c.Delete(i, 1);
    	c.Insert(",", i);
    
       AnsiString d = s.SubString(19, 17);
       i = d.Pos(".");
       d.Delete(i, 1);
    	d.Insert(",", i);
    
    	double concentration = StrToFloat(c);
       double pressure = StrToFloat(d);
    	Label1->Caption = c;
       Label2->Caption = d;
    }
    


  • schon die ganze Zeit probiert, aber es treten immer wieder Probleme auf. Z.B. Variert die Anzahl die Stringlänge je nachdem ob die Werte Vorzeichen haben oder nicht. Ich hätte noch eine andere Idee. Bevor ich den String hatte hhab ich ihn aus einem char-Array umgewandelt.
    Vielleicht ist es einfacher das chararray mit einer for-Schleife zu durchlaufen und dann mit if-Abfragen die einzelnen Fälle durchzugehen. Wenn true wird das aktuelle Feld in ein neues char-Array geschrieben. Hier mal mein Versuch:

    char x[30];
    if (CBuffer[0] != '\0')
          {
             for (int i=0; i<50; i++)
             {
                if (CBuffer[i] == '-') //CBuffer ist das char-Array mit 50 Elementen 
                   x[i] = '-';
                if (CBuffer[i] == '.')
                	x[i] = ',';
                if (CBuffer[i] >= 48 || CBuffer[i] <= 57) //zwischen 0 und 1
                   x[i] = CBuffer[i]; //???
                if (CBuffer[i] == ' ')
                	break;
             }
          }
    

    den Punkt ersetzt er mir nicht und auch buchstaben werden mit geschrieben obwohl ich doch sage, dass er nur Zahlen von 0 bis 9 nehmen soll.



  • Vielleicht kann dir meine open-source-Funktion dtoa() weiterhelfen. Du findest sie auf meiner Homepage http://bernienutt.npage.de als Download.


Anmelden zum Antworten