nur bestimmte Zeilen einer Textdatei auslesen



  • Hallo,

    programmiere gerade wie man Textdateien auslesen kann. Jetzt möchte ich dass aber nur bestimmte zeilen ausgelesen werden, z.b.: wenn eine Zeile mit .Stimulus beginnt.

    kann mir da jemand helfen?

    der Quellcode bislang:

    void CTestneuDlg::OnBnClickedButton2() //Button "Datei auswählen" 
    {
    	CString pathName;  //Variable pathName vom Typ CString wird deklariert
    	TCHAR szFilters[]= _T("Text Files (*.txt)|*.txt|All Files (*.*)|*.*||"); //Filter, dass nur .txt-Dateien angezeigt werden
    	CFileDialog fileDlg( TRUE, _T("txt"), _T("*.txt"), OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilters); // Klasse CFileDialog wird mit Argumenten beschrieben
    
    	 if( fileDlg.DoModal() == IDOK) //Bedingung für den "Open File Dialog"
    	 {
    		CFile Quelldatei; //Klasse CFile wird verwendet, Quelldatei vom Typ CFile
    
    		pathName = fileDlg.GetPathName(); //von Klasse fileDlg.: nimmt Pfad der Datei und übergibt sie an die Variable pathname
    
    			if(!Quelldatei.Open(pathName, CFile::modeNoInherit ,NULL)) //Überprüfung ob Datei nicht geöffnet ist, falls ja, Fehlermeldung in Messagebox
    			{	
    				CString text = _T("Datei konnte nicht geöffnet werden! Bitte Vorgang wiederholen"); //Text als CString deklarieren
    				MessageBox(text); //Ausgabe in Message (nur im Fehlerfall)
    			}
    
    			else
    			{
    				int size = Quelldatei.GetLength(); //Länge der Quelldatei wird in die integer-Variable size übergeben, size = Anzahl der Zeichen der vom Benutzer ausgewählten Datei
    
    				char *buffer = (char*) calloc ( size+1, sizeof(char) ); //calloc reserviert im Speicher einen Bereich von der Größe size vom Typ char
    
    				Quelldatei.Read(buffer, size); //Quelldatei wird ausgelesen, liest Zeichen für Zeichen aus, bis Endwert von "size" erreicht wird und schreibt Inhalt in "buffer"
    
    				CString buffer_str = (CString)buffer; //übergebe Speicherbereich "buffer"an Variable "buffer_str" vom Typ CString übergeben, damit allokierter Bereich wieder freigegeben werden kann
    
    				free(buffer); //gibt allocierten Speicher wieder frei, da PC sonst Speicher nicht mehr nutzen kann solange das Programm ausgeführt wird
    
    				CString row; // Variable "row" vom Typ CString, 
    				int zeichenzaehler = 0; 
    				int reihenzaehler = 0; 
    
    				while(zeichenzaehler < buffer_str.GetLength() && buffer_str[zeichenzaehler] != '\n')  
    				{
    
    					row.Insert(reihenzaehler, buffer_str[zeichenzaehler]); 
    					zeichenzaehler++; hochsetzen für nächstes Zeichen auszulesen
    					m_textbox.SetWindowTextW(buffer_str); //Ausgabe der Zeile in Textbox
    
    				}
    
    			}		
    	 }
    }
    


  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum MFC (Visual C++) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Also, wenn du das mit MFC machst, dann lies doch ie Zeilen in Variablen vom Typ CString ein. Weiterhin könntest du auch die Klasse CStdioFile verwenden, die schon das zeilenweise Auslesen vereinfacht.
    Bei CString sind dann .Find, .Left oder .Right deine Freunde.



  • Stutzpeter schrieb:

    Hallo,

    programmiere gerade wie man Textdateien auslesen kann. Jetzt möchte ich dass aber nur bestimmte zeilen ausgelesen werden, z.b.: wenn eine Zeile mit .Stimulus beginnt.

    Das geht nicht. Du kannst nur alle Zeilen lesen (evtl. nach und nach, also eine nach der anderen), prüfen, ob sie mit .Stimulus beginnt, und abhängig von dieser Prüfung sie entweder verwerfen oder anderweitig mit ihr verfahren.



  • ok, danke.

    jetzt bleibt nur die Frage wie ich das machen kann.

    ich lese die datei ein und gebe sie in einer Textbox aus. jetzt möchte ich die textbox zeilenweise auslesen, am liebsten mit getline. aber bei der textbox komme ich nicht auf die richtige syntax.


  • Mod

    Wenn Du ein Edit Control verwendest kannst Du doch zeilenweise darauf zugreifen.
    CEdit::GetLine



  • meinst du so?

    textbox::GetLine();
    

    das klappt leider nicht, weil Fehlermeldung: " 3 IntelliSense: Ein Name gefolgt von "::" muss ein Klassen- oder Namespacename sein."



  • mein Vorschlag zum Problem:

    CString pathName;  //Variable pathName vom Typ CString wird deklariert
        TCHAR szFilters[]= _T("Text Files (*.txt)|*.txt|All Files (*.*)|*.*||"); //Filter, dass nur .txt-Dateien angezeigt werden
        CFileDialog fileDlg( TRUE, _T("txt"), _T("*.txt"), OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilters); // Klasse CFileDialog wird mit Argumenten beschrieben
    
         if( fileDlg.DoModal() == IDOK) //Bedingung für den "Open File Dialog"
         {
            CStdioFile Quelldatei; //Klasse CFile wird verwendet, Quelldatei vom Typ CFile
    
            pathName = fileDlg.GetPathName(); //von Klasse fileDlg.: nimmt Pfad der Datei und übergibt sie an die Variable pathname
    
                if(!Quelldatei.Open(pathName, CFile::modeNoInherit ,NULL)) //Überprüfung ob Datei nicht geöffnet ist, falls ja, Fehlermeldung in Messagebox
                {   
                    CString text = _T("Datei konnte nicht geöffnet werden! Bitte Vorgang wiederholen"); //Text als CString deklarieren
                    MessageBox(text); //Ausgabe in Message (nur im Fehlerfall)
                }
    
                else
                {
                    int size = Quelldatei.GetLength(); //Länge der Quelldatei wird in die integer-Variable size übergeben, size = Anzahl der Zeichen der vom Benutzer ausgewählten Datei
    
                    CString buffer_str; //übergebe Speicherbereich "buffer"an Variable "buffer_str" vom Typ CString übergeben, damit allokierter Bereich wieder freigegeben werden kann
    
    				int zeichenzaehler = 0;  
    				while(Quelldatei.ReadString(buffer_str) == TRUE) //Quelldatei wird ausgelesen, liest Zeilenweise ein
    				{
    					if(buffer_str.Mid(0,9) == _T(".Stimulus")) //vergleichen ob die ersten 9 zeichen mit .Stimulus übereinstimmen
    					{
    						zeichenzaehler++; //hochsetzen für nächstes Zeichen auszulesen
    						m_Edit.SetWindowText(buffer_str); //Ausgabe der Zeile in Textbox 
    					}
    				}
    
                }       
         } 
    }
    


  • @CTecS:

    erstmal Vielen Dank. Den .mid kannte ich bislang nicht. funktioniert soweit, allerdings:

    wenn eine Zeile mit .Stimulus beginnt wird sie in der Textbox geschrieben.

    Wenn eine weitere Zeile mit .Stimulus beginnt, führt es dazu dass die erste Zeile in der Textbox überschrieben wird. Obwohl ich in den Einstellungen multiline aktiviert habe...

    Woran mag das liegen, selbst wenn ich meinen Quellcode mit deinem verschachtele, kompiliert VS, ich kann die Datei öffnen, aber trotzdem erscheint immer nur die letzte Zeile in der Textbox, zum verrückt werden -.-



  • Das liegt daran das SetWindowText() den Kompletten Text deiner Textbox mit dem übergebenen "ersetzt", also gibt es 2 Möglichkeiten um dein Ziel zu erreichen.

    beides nur Codeabschnitte die du entsprechen einsetzen musst.

    Möglichkeit 1:

    einen Buffer benutzen in dem der neue Text angefügt wird und dann mit SetWindowText() gesetzt wird

    CString buffer_str; //übergebe Speicherbereich "buffer"an Variable "buffer_str" vom Typ CString übergeben, damit allokierter Bereich wieder freigegeben werden kann
                    CString tmp; //Buffer für Ausgabe 
    
                    int zeichenzaehler = 0;  
                    while(Quelldatei.ReadString(buffer_str) == TRUE) //Quelldatei wird ausgelesen, liest Zeilenweise ein
                    {
                        if(buffer_str.Mid(0,9) == _T(".Stimulus")) //vergleichen ob die ersten 9 zeichen mit .Stimulus übereinstimmen
                        {
                            zeichenzaehler++; //hochsetzen für nächstes Zeichen auszulesen
                            tmp += buffer_str + _T("\r\n");
                            m_Edit.SetWindowText(tmp); //Ausgabe der Zeile in Textbox
                        }
                    }
    

    Möglichkeit 2:
    Den Text mit GetWindowText() aus der EditBox holen, neuen Text Anfügen und wieder mit SetWindowText() setzten

    CString buffer_str; //übergebe Speicherbereich "buffer"an Variable "buffer_str" vom Typ CString übergeben, damit allokierter Bereich wieder freigegeben werden kann
                    CString tmp; //Buffer für Ausgabe 
    
                    int zeichenzaehler = 0;  
                    while(Quelldatei.ReadString(buffer_str) == TRUE) //Quelldatei wird ausgelesen, liest Zeilenweise ein
                    {
                        if(buffer_str.Mid(0,9) == _T(".Stimulus")) //vergleichen ob die ersten 9 zeichen mit .Stimulus übereinstimmen
                        {
                            zeichenzaehler++; //hochsetzen für nächstes Zeichen auszulesen
                            m_Edit.GetWindowText(tmp);
                            tmp += buffer_str + _T("\r\n");
                            m_Edit.SetWindowText(tmp); //Ausgabe der Zeile in Textbox
                        }
                    }
    

    Wobei wie man sieht ist die Möglichkeit 1 die bessere weil nicht extra der Text wieder zurückgelesen werden muß.

    _T("\r\n") = Erzeugt den Zeilenumbruch damit nicht alles in einer Zeile steht

    und sorry wenn ich das sage aber dein Codeabschnitt den du da gebaut hast ist grausam und calloc in MFC eine Totsünde, dafür gibt es new und delete



  • Also erstmal danke für den Support, funktioniert natürlich einwandfrei.

    Zu meinem Code: das kommt halt dabei raus wenn ein Elektroingenieur programmiert, da macht man halt mehr in VHDL oder Basic oder Assembler 😉



  • Stutzpeter schrieb:

    Zu meinem Code: das kommt halt dabei raus wenn ein Elektroingenieur programmiert, da macht man halt mehr in VHDL oder Basic oder Assembler 😉

    Das kann man so nicht sagen. Bin auch Elektroingenieur und hab nie in Basic oder VHDL programmiert. Aber nur an solchen Projekten lernt man dazu und etwickelt sich weiter. Das nächste Mal weißte ja jetzt wie es geht...



  • Kommt wohl auch auf die Vertiefungsrichtung an. Ich würde gerne noch so viele Programmiersprachen beherrschen, wie Java z.b. aber das is zeitlich überhaupt nicht möglich...


Anmelden zum Antworten