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.
-
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 } } } } }
-
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() setztenCString 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...