Textbox zeilenweise auslesen



  • Hallo, ich möchte nun eine Textbox zeilenweise auslesen und die Daten anschließend weiter verarbeiten. Im unteren Beispiel möchte ich den Inhalt lediglich in einer zweiten Textbox darstellen, um zu testen ob richtig ausgelesen wird:

    was mache ich da falsch?

    void CTestneuDlg::OnBnClickedButton2()  
    {
    		int i = 0;
    	int zeilen = m_textbox.GetLineCount();
    	for(i=0; i < zeilen; i++)
        {
    		CString str;
    
            m_textbox.GetLine(i, str.GetBuffer( m_textbox.LineLength(i)),    m_textbox.LineLength(i));
            str.ReleaseBuffer();
    		m_textbox1.SetWindowTextW(str);
            str.Empty();
        }
    }
    


  • Du hast die Fehlerbeschreibung vergessen...



  • Ach Mist hatte den falschen Quellcode gepostet, oben steht jetzt der richtige.

    Also das Problem:

    wenn ich manuell eine mehrzeilige Textbox Eingabe in Textbox 1 mache, und auf den Button klicke hinter dem der Quellcode hinterlegt ist, liest er ganz seltsam aus, manchmal die 1. oder die 3. Zeile. für mich kein Muster zu erkennen. Wenn ich nur eine Zeile eingebe (ohne Enter zu drücken), die liest er korrekt aus und stellt sie in Textbox 2 dar. (mit eingegebener Enter-Taste liest er nichts aus)



  • der Fehler wurde nun erkannt:

    in Textbox 2 wird immer nur die letzte Zeile von Textbox 1 ausgegeben, allerdings immer nur soviel Zeichen, wie in der ersten Zeile stehen...

    Beispiel:

    in Textbox1 schreibe ich:

    hallo
    welt
    herrlich

    dann steht in Textbox2:

    herrl

    und ich komm einfach nicht dahinter wieso er es tut



  • So hab mal wieder an deinem Source gebastelt und das ein bischen gerichtet

    int i = 0;
        int zeilen = textbox.GetLineCount();
        CString str; //erspaart dauerdes neuanlegen
        for(i=0; i < zeilen; i++)
        {
    		int Index = textbox.LineIndex(i);  //gibt den Index der zeile zurück
            int lenght = textbox.LineLength(Index); 
            textbox.GetLine(i, str.GetBuffer( lenght ), lenght );
            str.ReleaseBuffer();
            textbox1.SetWindowText(str);
            //str.Empty(); //kann man weglassen da der Scope der Variable hier eh beendet ist und diese nicht mehr existiert
        }
    

    Wobei du hättest bei deine ersten thread bleiben können und dort einfach die frage weiter stellen können, wegen jeden kleinen problem was ja nun änlich deinem ersten ist einen neuen thread zu eröffnen ist sicher auch nicht sinn und zweck der übung



  • Wenn du str aus dem Scope rausnimmst, kannst du aber mit dieser Begründung nicht mehr auf Empty verzichten. 😉



  • _matze schrieb:

    Wenn du str aus dem Scope rausnimmst, kannst du aber mit dieser Begründung nicht mehr auf Empty verzichten. 😉

    Da muss ich dir recht geben, aber wirderum brauch ich trotzdem kein Empty da ich ja den Buffer des CStrings überschreibe (GetBuffer) und dann meinen CString aktualisiere (ReleaseBuffer), den Rest macht der CString eh intern also warum alles doppelt machen und dann noch mal extra Empty aufrufen?

    wobei das ganze ist sicherlich bischen unglücklich ausgedrückt wenn ich das Empty ankreide aber den CString aus dem Scope nehme, aber das mit dem Empty war so gedacht wenn der String im scope der Schleife verbleibt 😉



  • Also mit diesem Code funktioniert es einwandfrei:
    vielen dank dafür

    CString buffer;
    	int i = 0;
        int zeilen = m_textbox.GetLineCount();
        CString str; //erspaart dauerdes neuanlegen
        for(i=0; i < zeilen; i++)
        {
            int Index = m_textbox.LineIndex(i);  //gibt den Index der zeile zurück
            int lenght = m_textbox.LineLength(Index);
            m_textbox.GetLine(i, str.GetBuffer( lenght ), lenght );
            str.ReleaseBuffer();
    
    		buffer += str + _T("\r\n"); 
    		m_textbox1.SetWindowTextW(buffer);	
    		Sleep(500);
    		str.Empty(); //Lösche Inhalt der Variable str
    
    	}
    

    die Zeitverzögerung Sleep(500) funktioniert zwar aber leider nicht nach einer Zeile, sprich wenn ich 3 Zeilen in m_textbox eingebe, wartet er 3x500ms und gibt dann alle 3 Zeilen gleichzeitig in m_textbox1 aus... jemand grade nen kleinen Tipp?



  • Hilft vielleicht ein RedrawWindow?



  • Nein da hilft auch kein RedrawWindow().

    Der Sleep hält den Programmablauf an, was eigentlich gewollt und doch wieder ungewollt ist, da alles was unter Windows gemacht wird über Messages gemacht wird. Der Messageloop der benötigt wird um die Nachrichten abzuarbeiten wird aber bei Sleeo() nicht ausgeführt, so das du auch keine Veränderungen an deinem Dialog siehst, die lösung ist sich selbst ein sleep zu bauen welches den Messageloop edient und gleichzeitig eine bestimmte Zeit wartet.

    so in etwa (nicht getestet also kann fehlerhaft sein):

    void _sleep(DWORD mSec)
    {
    DWORD _StartTime = GetTickCount();
    MSG msg;
    
    while( ::PeekMessage( &msg, NULL, NULL, NULL, PM_NOREMOVE ) )
    {
        ::AfxGetThread()->PumpMessage();
        if(mSec < _StartTime + GetTickCount())
            sleep(5);
        else
            break;
    }
    }
    

    den sleep (5) kann man auch durch sleep(1) ersetzen was die auflösung erhöht, ist halt die frage ob man das unbedingt millisekunden genau haben will oder ob da ne abweichung auch möglich sein kann. Wie gesagt is nur im kopf entwickelt nie getestet wurden also kann noch fehler enthalten oder so auch gar net gehen, soll aber veranschauligen was das problem ist

    siehe auch MFC-FAQ:7.15 Wie kann ich eine eigene Messageloop implementieren?


  • Mod

    Also mit einem UpdateWindow direkt nach dem SetWindowText sollte es gehen.
    Da benötigt man keine extra eigene Message Loop wenn man keine Benutzerinteraktion benötigt.



  • Der Quellcode funktioniert natürlich, wie immer 😉

    Vielen Dank an alle!



  • Ich bins wieder, habs mittlerweile soweit dass ich aus einem Textfeld, in dem folgendes drin steht:

    + +0s 11100000
    + 1200ms 10101010
    + 1600ns 11001101

    sowohl die Zeiten als auch die Einheit auslesen kann. Allerdings beim Ausgeben der wesentlichen Daten in ein zweites Textfeld, sieht unter untem stehenden Quellcode das Ausgelesene so aus:

    0s
    1200ms
    s
    s
    1600ns

    int i = 0; // Zähler 
        int Anzahl_Zeilen = m_textbox.GetLineCount(); //CEdit Member "GetLineCount()": zählt wieviele Zeilen des Textfeldes mit Daten beschrieben sind
        CString Zeileninhalt; //Variable "Zeileninhalt" vom Typ CString deklarieren
        CString Ausgabe; //Variable "Ausgabe" vom Typ CString deklarieren
    	CString Suchtext; //Variable "Suchtext" vom Typ CString deklarieren
    	CString Ausg;
    
    	for(i=0; i < Anzahl_Zeilen; i++) //Schleifenzähler, bis alle Zeilen abgearbeitet sind
    
        {		
            int Zeilen_Index = m_textbox.LineIndex(i);  //gibt den Index der zeile zurück
            int Zeilen_Laenge = m_textbox.LineLength(Zeilen_Index); //gibt die Länge der entsprechenden Zeile zurück
            m_textbox.GetLine(i, Zeileninhalt.GetBuffer( Zeilen_Laenge ), Zeilen_Laenge ); //CEdit Member "GetLine()": Zeileninhalt des Eingabefeldes auslesen
            Zeileninhalt.ReleaseBuffer(); //Speicher für Zeileninhalt freigeben
    
    		 //CString Member "Find()", Sucht jede Zeile Zeichen für Zeichen nach Substring "ms" ab
    		size_t g = Zeileninhalt.Find(_T("ms"));	
    		size_t h = Zeileninhalt.Find(_T("s"));	
    		size_t f = Zeileninhalt.Find(_T("ns"));	
    
    		if (g != -1) //Falls Cursorposition > -1
    		{		
    
    			while (--g >= 0 && Zeileninhalt[g] >= '0' && Zeileninhalt[g] <= '9' || Zeileninhalt[g] == '.') //sucht von ""Suchtext"" ausgehend zum Dateianfang alle Zeichen nach Ziffern oder Punkte (für Kommazahlen) ab 
    			{
    				Suchtext = Zeileninhalt[g] + Suchtext; // gefundene Ziffern oder Punkte werden stringgemäß aneinander gereiht
    			}
    			Ausgabe += Suchtext + _T("ms") + _T("\r\n");
    			Suchtext.Empty();
    
    			m_textbox1.SetWindowTextW(Ausgabe);//Ausgabe im Textfeld
    			Ausg.Empty();
    		}
    
    		if (h != -1) //Falls Cursorposition > -1
    		{		
    
    			while (--h >= 0 && Zeileninhalt[h] >= '0' && Zeileninhalt[h] <= '9' || Zeileninhalt[h] == '.') //sucht von ""Suchtext"" ausgehend zum Dateianfang alle Zeichen nach Ziffern oder Punkte (für Kommazahlen) ab 
    			{
    				Suchtext = Zeileninhalt[h] + Suchtext; // gefundene Ziffern oder Punkte werden stringgemäß aneinander gereiht
    			}
    
    			Ausgabe += Suchtext + _T("s") + _T("\r\n");
    			Suchtext.Empty();
    			m_textbox1.SetWindowTextW(Ausgabe);//Ausgabe im Textfeld
    			Ausg.Empty();
    		}
    
    		if (f != -1) //Falls Cursorposition > -1
    		{		
    
    			while (--f >= 0 && Zeileninhalt[f] >= '0' && Zeileninhalt[f] <= '9' || Zeileninhalt[f] == '.') //sucht von ""Suchtext"" ausgehend zum Dateianfang alle Zeichen nach Ziffern oder Punkte (für Kommazahlen) ab 
    			{
    				Suchtext = Zeileninhalt[f] + Suchtext; // gefundene Ziffern oder Punkte werden stringgemäß aneinander gereiht
    			}
    
    			Ausgabe += Suchtext + _T("ns") + _T("\r\n");
    			Suchtext.Empty();
    			m_textbox1.SetWindowTextW(Ausgabe);//Ausgabe im Textfeld
    			Ausg.Empty();
    		}
    	}
    

    Hat jemand eine Idee warum das so ist? Bin am verzweifeln, hocke seit tagen dran und komme einfach nicht drauf...



  • aber du weisst schon das

    size_t h = Zeileninhalt.Find(_T("s"));
    

    dir immer einen treffer bringt auch wenn du in der zeile "ms" oder "ns" steht, also müsstest du zumindest als erstes nach "ms" und "ns" suchen und wenn b eides nicht gefunden wurde suchst du nach "s" und dann weisste was in der zeile steht, alsomusst du schon beim ersten treffer schon aufhören mit suchen sonst bekommst du fehler beim auslesen.

    hab mal wieder bissel gebastelt, aber weis net ob das so geht weil nicht getestet

    void Ausgabe(int g, CString &Zeileninhalt, CString &suffix)
    {
    	CString Ausgabe; //Variable "Ausgabe" vom Typ CString deklarieren
        CString Suchtext; //Variable "Suchtext" vom Typ CString deklarieren
        CString Ausg;
    
    	while (--g >= 0 && Zeileninhalt[g] >= '0' && Zeileninhalt[g] <= '9' || Zeileninhalt[g] == '.') //sucht von ""Suchtext"" ausgehend zum Dateianfang alle Zeichen nach Ziffern oder Punkte (für Kommazahlen) ab
        {
            Suchtext = Zeileninhalt[g] + Suchtext; // gefundene Ziffern oder Punkte werden stringgemäß aneinander gereiht
        }
        Ausgabe += Suchtext + suffix + _T("\r\n");
        Suchtext.Empty();
    
        m_textbox1.SetWindowTextW(Ausgabe);//Ausgabe im Textfeld
        Ausg.Empty();
    
    }
    
    //deine routine die ich bischen gekürzt habe
    	int i = 0; // Zähler
        int Anzahl_Zeilen = m_textbox.GetLineCount(); //CEdit Member "GetLineCount()": zählt wieviele Zeilen des Textfeldes mit Daten beschrieben sind
        CString Zeileninhalt; //Variable "Zeileninhalt" vom Typ CString deklarieren
    
        for(i=0; i < Anzahl_Zeilen; i++) //Schleifenzähler, bis alle Zeilen abgearbeitet sind
        {       
            int Zeilen_Index = m_textbox.LineIndex(i);  //gibt den Index der zeile zurück
            int Zeilen_Laenge = m_textbox.LineLength(Zeilen_Index); //gibt die Länge der entsprechenden Zeile zurück
            m_textbox.GetLine(i, Zeileninhalt.GetBuffer( Zeilen_Laenge ), Zeilen_Laenge ); //CEdit Member "GetLine()": Zeileninhalt des Eingabefeldes auslesen
            Zeileninhalt.ReleaseBuffer(); //Speicher für Zeileninhalt freigeben
    
             //CString Member "Find()", Sucht jede Zeile Zeichen für Zeichen nach Substring "ms"
    		size_t g;
    
    		CStringArray suffix;
    		suffix.Add(_T("ms"));
    		suffix.Add(_T("ns"));
    		suffix.Add(_T("s"));
    
    		for(int t= 0;t<3;t++)
    			if(g = Zeileninhalt.Find(suffix[t])!= -1)
    			{
    				Ausgabe(g,Zeileninhalt,suffix[t]);
    				break;
    			}
        }
    

    und irgendwas stimmt noch nicht bei deiner sucherei also in der funktion ausgabe, aber da ich nicht wirklich genau weis was du da an werten haben willst hab ich nicht weiter gesucht



  • Vielen Dank!

    Das mit dem Array hat mich zum nachdenken angeregt, wollte diesmal nicht c&p machen, sondern selbst hinbekommen

    klappt nun, kann sogar die Pegel rechts der Einheiten auslesen. Jetzt noch die Zeiten und die Pegel nach int konvertieren und fertig, hoffe das geht überhaupt


Anmelden zum Antworten