"LoadFromFile()" von TStringList liest nicht die ganze Datei ein



  • Hallo Leute,

    ich verwende BCB 5.0 Pro, und möchte mit TStringList eine Textdatei einlesen.

    Die Textdatei hat folgenden Inhalt:

    15:21:50:172	757,7	746,5	757,0	993,6	377,0
    15:21:50:188	757,7	748,5	760,2	993,7	377,0
    15:21:50:203	 	  	746,7	755,0	990,1
    15:21:50:219	757,5	751,2	753,5	992,2	368,2
    

    Alle Spalten sind durch ein Tab getrennt.
    In der Zeile 3 ist irgendein Sonderzeichen enthalten.

    Das Problem ist, dass die Funktion "LoadFromFile()" nur die ersten 2 Zeilen einliest. Wenn ich den "Count" von der Liste abfrage, dann gibt er mir "2" aus,
    obwohl die Textdatei 4 Zeilen hat.

    Weiss jemand, wie ich trotzdem den ganzen Dateiinhalt mit der TStringList
    auslesen kann?



  • Morchn,

    habe mir eben den Dateiinhalt in ein Textfile kopiert, mit LoadFromFile gelesen, und siehe da, 4 Zeilen drin 😕

    Zeig doch mal den kompletten Code zum lesen dieser Datei, also auch, wie du die TStringList erstellst, ...

    Habs mit TMemo getestet

    Memo1->Lines->LoadFromFile( "test.txt" );
    

    und da ist alles ok.

    grüssle 🙂



  • hallo,

    danke erstmal für die Mühe.

    Also ich habe das auch mit TMemo versucht. Mit dem gleichen Resultat: beim mir werden nur die ersten zwei Zeilen ins Memo geschrieben.
    Ich denke, dass dieses Sonderzeichen, was ich als Beispiel gezeigt habe, nicht das gleiche wie bei mir in der Textdatei ist, obwohl ich es durch Kopieren
    1 zu 1 ins Posting reingesetzt habe.

    Ich habe ein Screenshot von dem Dateiinhalt gemacht (Geöffnet mit Notepad):

    http://www.bilder-hochladen.net/files/eedh-1-jpg-nb.html

    Und mein Quellcode sieht so aus:

    TStringList *Zeilen_aus_Logdatei = new TStringList;
    Zeilen_aus_Logdatei->LoadFromFile(Pfad);
    delete Zeilen_aus_Logdatei;
    


  • Schau dir mal die Datei mit einem Hex-Editor an.
    Wenn darin das Zeichen mit dem ASCII-Code 26 (0x1A) vorkommt, dann gilt das für eine Textdatei als Endezeichen (dies entspricht Strg-Z). Dann wirst du eine andere Lesemthode verwenden müssen (und dann im Binärmodus öffnen!).

    Btw. warum hast du überhaupt Sonderzeichen darin?



  • Hallo

    Also um es nochmal konkreter zu sagen : sowohl TStringList als auch String sind nur für die Verarbeitung von Text-Dateien bzw. Text-Daten bestimmt. Der Versuch binäre Daten in einer der beiden Klassen zu laden, führt zu Datenverlust bzw. undefiniertem Verhalten. Binäre Dateien lassen sich korrekt nur mit Streams (TFileStream, std::fstream) im Binärmodus bzw. char-Arrays verarbeiten.

    bis bald
    akari



  • @ Th69:

    ich denke, dass die Sonderzeichen durch das zu schnelle Zugreifen auf die Textdatei reingebracht werden. Ich habe mal die Datei mit einem Hex-Editor nach 0x1A durchsucht, ohne Erfolg.

    Na ja, ich werde dann auf TFileStream umsteigen, wie Akari vorgeschlagen hat.

    Danke für alle Antworten.



  • Hallo

    sonic_1233 schrieb:

    ich denke, dass die Sonderzeichen durch das zu schnelle Zugreifen auf die Textdatei reingebracht werden.

    😕

    Ich habe mal die Datei mit einem Hex-Editor nach 0x1A durchsucht, ohne Erfolg.

    Na ja, ich werde dann auf TFileStream umsteigen, wie Akari vorgeschlagen hat.

    Was den nun, sind binäre Sonderzeichen drin oder nicht? Wenn nicht dann brauchst du eigentlich auch nicht umsteigen.

    bis bald
    akari



  • @ akari,
    Doch Sonderzeichen sind drin.

    In meine Logdateien wird etwa alle 20 ms neue Zeile angehängt, und ich dachte, dass dadurch Fehler beim Schreiben auftreten können, weil Windows damit nicht
    zurecht kommt.



  • So wie das auf dem Screenshot aussieht sind da NULL-Zeichen drin (also \0). Mein BCB 6 bricht beim ersten vorkommen von NULL sogar komplett ab, ich hab nru den Text bis dahin in der TStringList.

    Wie gesagt, die Datei könnte man mittels TFileStream im Binärmodus öffnen und in einer Schleife alle NULL-Zeichen oder sonstigen Zeichen durch Leerzeichen ersetzen und den Stream dann in ein TStringList einlesen.

    Allerdings solltest Du eher versuchen herauszufinden, wie die Zeichen da hineinkommen und das abstellen. Wenn da schon Zeichen drin sind, die da nicht hineingehören, dann würde ich dem restlichen Inhalt auch nicht mehr trauen...



  • Ok, danke für alle Vorschläge.
    Ich melde mich, wenn es läuft...



  • Also, falls es jemanden interessiert, ich bin doch auf "fstream" umgestiegen,
    und es funktioniert ganz gut. Alle Zeilen werden eingelesen.
    Ich kopiere alle Zeilen aus der Textdatei mit "getline()" in eine TStringList, und
    von der Liste aus werden die Zeilen ausgewertet.

    #include <fstream>
    
    string str_Zeile;
    AnsiString astr_Zeile_aus_Datei = "";
    
    // Speicherplatz reservieren:
    TStringList *Zeilen_aus_Logdatei = new TStringList;
    
    // Datei öffnen
    // =============
    DateiKomponente.open(Pfad.c_str(), ios::in);
    
    // Prüfen, ob die Datei geöffnet ist, und das Dateiformat in Ordnung ist
    // =====================================================================
    if(DateiKomponente.is_open() && DateiKomponente.good())
    {
     // Solange Zeilen einlesen, bis das Dateiende erreicht ist
     // =======================================================
     while(!DateiKomponente.eof())
     {
      // Eine Zeile aus der Datei in einen String kopieren
      getline(DateiKomponente, str_Zeile);
    
      // String nach AnsiString konvertieren
      // weil die Funktion "Add()" nur AnsiStrings akzeptiert
      astr_Zeile_aus_Datei = AnsiString(str_Zeile.c_str());
    
      // Zeile in eine Liste kopieren
      Zeilen_aus_Logdatei->Add(astr_Zeile_aus_Datei);
    
     }// End while, Solange Zeilen einlesen, bis das Dateiende erreicht ist
    
     // Datei schließen
     DateiKomponente.close();
    
    }
    
    // Speicherplatz freigeben
    delete Zeilen_aus_Logdatei;
    

    Gruß
    sonic


Log in to reply