Wie 'LF' und 'CR' im AnsiString löschen? + ComPort Problem.



  • Hi,
    ich bekomme von der Comschnittstelle einen Stream gesendet. Zur Portansteuerung benutze ich die ComPort Libary. Doch ich bekomme am Anfang schon ein 'CR' und 'LF' gesendet, so das der Text in der zweiten Reihe meines Memofensters steht. Was auch noch komisch ist, das ich die Daten vom ComPort (394 Zeichen) nicht in einem Rutsch empfange. Nach 112 zeichen wird ins Memo geschrieben und der Rest wieder an den Text gehängt.Also 112+112+112+112. Gibt es da eine Beschränkung, wenn mann Zeichen über den Comport empfängt. Was aber wichtiger ist, die 'CR' und 'LF' am anfang zu löschen.

    void __fastcall Tfrm_com_ansteuerung::ComPort3RxChar(TObject *Sender, int Count)
    {
         AnsiString varWT,Str3,WTnr,varWTREPLACE;
         ComPort3->ReadStr(Str3, Count); //Empfange String vom ComPort
    
         memo_com3->Text = memo_com3->Text + Str3; //Empfangenen String vom ComPort
                                                   //ausgeben
    
         WTnr=memo_com3->Text;          //Empfangenen Text WTnr zuordnen, da die
                                        //Daten vom ComPort in Str3 nicht in einem
                                        //Rutsch gelesen werden.
                                        //Es werden die Daten wohl in einen Buffer
                                        //gelesen, wenn dieser voll ist wird nach
                                        //memo_com3->Text geschrieben.
                                        //Dann wird der Buffer wieder gefüllt und
                                        //wieder in memo_com3->Text geschrieben.
                                        //Deshalb die Variable WTnr um nicht mehrer
                                        //Datein zu erzeugen.
    
         varWT=WTnr.SubString(10,5);   //Zeichen Isolieren um Textnamen zu erzeugen
         varWTREPLACE = StringReplace(varWT, " ", "", TReplaceFlags() << rfReplaceAll << rfIgnoreCase); //Lehrzeichen im isoliertem String löschen
    
          try
        {
      memo_com3->Lines->SaveToFile("WT" +varWTREPLACE+".txt"); //String in Textdatei speichern, Dateinamen erzeugen
    
        }
        catch (Exception& e)                      //Fehlermeldung abfangen
        {
            String className = e.ClassName();
            String msg = e.Message;
        }
    
    }
    

    Jemand eine Idee?

    Gruß
    Kohli



  • Guten Morgen kohliman,
    in der Hilfe zu AnsiString findest du die Methode

    AnsiString& __fastcall Delete(int index, int count);
    

    Die solltest du dir mal genauer ansehen und zum löschen der zeichen verwenden.

    Zu dem COM-Port fällt mir im Moment nur ein, dass du den Puffer des Comport auf einen Anzahl Zeichen setzen kannst ab der die empfangenen Daten weitergegeben werden. Diese Zahl enspricht natürlich nicht deiner Stringlänge. Ich suche in einem solchen Fall immer nach einem Anfang und einem Ende (konstante Zeichenfolge) des String sofort bei dem Empfang des Strings. Ist das nicht möglich und die Länge ist immer die gleiche zähl einfach die char.

    Viel Erfolg
    Evi48



  • Hi,
    erst mal danke für die Antwort. Das Problem mit dem 'CR' und 'LF' habe ich mit TrimLeft gelöst. Scheint gut zu klappen. Das mit dem ComPort ist so eine Sache. Habe schon mal den Buffer erhöt, aber leider ohne Erfolg. Das andere, was du da beschrieben hast, habe ich noch nicht so ganz verstanden. Arbeit noch nicht lange mit dem Builder. Wurde dazu gezwungen 🙂 Kannst Du mir da ein Beispiel geben.

    Gruß
    Kohli



  • Hi kohliman,
    hast du für den COM-Port die API-Funktionen genutzt oder benutzt du ein zugekauftes Tool? Ein Beispiel müsste ich erst wieder aus dem Archiv auf den Server laden lassen das kann etwas dauern.

    Du schreibst ein Schieberegister z.B. mit einer Länge von 5 char. Befor du ein Zeichen an der Stelle 0 in das array schreibst verschiebst du die Zeichen im array um ein byte in Richtung MSB. Dann vergleichst du den Inhalt des Arrays mit einem vorgegebenen Wert. Bei Übereinstimmung hast du den Anfang des Strings gefunden und speicherst die weiteren Zeichen als Nutzdaten bis du auf die gleiche Weise das Ende des String erkannt hast oder bis eine vorgegebene Anzahl Zeichen erreicht ist. Dann beginnt das Spiel von vorn.

    Evi48



  • Hallo evi48,
    ich benutze ein Tool "ComPort Library" ist Freeware. http://sourceforge.net/project/showfiles.php?group_id=76595
    ich finde das Tool echt klasse. Aber die Doku ist in Delphi und nicht ganz so ausführlich, so das ich das verstehe. Bin halt absoluter Neuling und mache das im zuge einer Projektarbeit zun Informatiktechniker. Bin ja schon ganz Stolz so weit gekommen zu sein :-). Also ein Beispiel wäre echt klasse, auch wenn es länger dauert. Desweiteren bekomme ich immer die gleiche Zeichenlänge von einem MessPC (394 Zeichen). Leider nicht in einem Rutsch, was ich nicht so ganz verstehe, da der Port doch eigendlich so viel Buffern müste. Habe auch schon den Buffer von 1024 auf 4096 erhöt, bringt aber nichts.

    Schon mal vielen Dank für deine Hilfe. Echt klasse hier.

    Gruß
    Kohli



  • Hallo kohliman,
    war auf Dienstreise tut mir leid.

    Also mit der Freeeware habe ich nicht die geringste Kenne was da genau gemacht wird.

    Hat dein String immer die gleiche Zeichenfolge am Anfang? Wenn nein woher weißt du dann wo die relevanten Daten für dich in dem Zeichenstrom stehen?
    Hat dein String immer die gleiche Länge 394 Zeichen?
    Handelt es sich um ASCII oder binaere Daten die empfangen werden. So dass der Datenstrom auch mal eine NULL enthalten kann und dadurch zusätzliche unterbrechungen für einen ASCII-String entstehen der ja mit NULL abgeschlossen wird?

    Evi48



  • evi48 schrieb:

    Hat dein String immer die gleiche Zeichenfolge am Anfang?
    Ja, hat er.

    Hat dein String immer die gleiche Länge 394 Zeichen?
    Ja, immer 394 Zeichen.
    Und als Endkennung werden ein "CR" und "LF" gesendet.

    Handelt es sich um ASCII oder binaere Daten die empfangen werden.
    ASCII
    Evi48

    Gruß
    Kohli



  • Hallo kohliman,

    so ein kleines Beispiel mit einzelen Funktionen die du in der richtigen Reihenfolge in dein Programm einbauen mußt.

    const char LF = char(10);	//LF
    	const char CR = char(13);	//CR
    	char	cStart[7]	= "$GPGGA";
    	char	cSchieb[7];
    	char	cData[395];
    	char	cNewChar[2];
    	bool	bAnfang = false;
    
    	if(!bAnfang)
    		strcpy(cSchieb, "");
    
    	// Verschieben der Char um den Anfang eines Datenstromes zu finden
    	for (int i = 5; i >= 0; i--)
    	{
    		cSchieb[i+1] = cSchieb[i];
    	}
    
    	// Ein neues Zeichen in das Schieberegister schreiben
    	cSchieb[0]		= cNewChar[0];
    
    	// Ist das der Anfang des Datenstromes
    	if (strcmp(cSchieb, cStart) == 0)
    	{
    		// Anfang gefunden und retten
    		strcpy (cData, cSchieb);
    		bAnfang	= true;
    	}
    
    	// Daten speichern
    	if (bAnfang)
    	{
    		strcat(cData, cNewChar);
    		if(cNewChar[0] == char(LF))
    			bAnfang	= false;
    	}
    }
    

    Du liest die Zeichen an dem COM-Port so lange bis du LF gefunden hast und beginnst dann wieder mit der suche des Start-String.

    Viel Erflog bis Morgen für mich ist heute Feierabend
    Evi48



  • Hi,
    vielen Dank für deine Mühe. Habe es hinbekommen.

    Vielen Dank.

    Gruß
    Kohli



  • Hallo kohliman,
    ich wünsche dir viel Erfolg

    Evi48


Log in to reply