Datei zeichenweise einlesen



  • Hallo zusammen,

    ich hab ein Problem mit dem zeichenweisen Einlesen einer Datei.

    try {
    		tfs = new TFileStream("temp.txt", fmOpenRead);
    		const int SIZE = 1;
    		char* c = new char[SIZE];
    
    		tfs->Read(c, SIZE);
    
    		Memo1->Lines->Add(c) ;
    	}
    

    Die Datei "temp.txt" enthällt nur das Wort "Hallo".

    Mit dem Code sollte doch eigentlich nur ein Buchstabe, hier eben "H", ausgegeben werden. Ich bekomme aber 2 ausgegeben und zwar "H" und ein zweites "AE^a". Hab gerade noch versucht 2 und 3 Zeichen auszugeben, ab 3 Zeichen funktioniert das einwandfrei. Bei 2 Zeichen stimmt die Ausgabe auch nicht.

    Könnt ihr mir evtl. dieses Verhalten erklären?

    Schon mal vielen Dank im Voraus.

    Gruß

    Arno



  • Hallo

    Read arbeitet schon richtig und liest genau ein Zeichen ein. Aber du verwendest einen C-String, und C-Strings müßen mit '\0' terminiert werden bevor sie weiterverarbeitet werden. Ohne Terminierung verursacht die Konvertierung in AnsiString dann ungültiges Verhalten, das sich hier eben in seltsamen Buchstaben äußert.
    Korrekt sähe es also so aus :

    try {
            tfs = new TFileStream("temp.txt", fmOpenRead);
            const int SIZE = 1;
            char* c = new char[SIZE +1]; // Ein Platz mehr fürs Terminieren
    
            tfs->Read(c, SIZE);
            c[SIZE] = '\0'; // Terminieren
    
            Memo1->Lines->Add(c) ;
            delete c[]; // Löschen nicht vergessen!
        }
    

    Wenn du nur jeweils ein Zeichen einlesen willst brauchst du übrigens gar nicht mit C-Strings hantieren

    try {
            tfs = new TFileStream("temp.txt", fmOpenRead);
            char c;
    
            tfs->Read(&c, 1);
    
            Memo1->Lines->Add(AnsiString() + c) ;
        }
    

    In dem gezeigten Code fehlt natürlich noch die Auswertung ob und wieviele Zeichen denn nun wirklich eingelesen wurden (wird von Read zurückgegeben). Denn wenn die Datei leer ist kommt es so immer noch zu Fehlern.

    bis bald
    akari



  • Vielen Dank für die schnelle Antwort Akari.

    Ist aber schon merkwürdig, dass das Array wirklich 4 Zeichen groß ist.



  • Hallo habe da ein problem, ich bin dabei meine kenntnisse in c++ zu erweitern.dazu benutze ich das c++ in 21 tagen buch. mit der zeit nerven die zeilennummern die man jedesmal von hand entfernen muss um den quellcode zu benutzen. ich habe schon ein programm geschrieben mit dem man EIN zeichen weg bekommt. aber damit bekommt man keine fortlaufenden zahlen weg. ich habe schon viel gegooglt aber nix passendes gefunden.ich bitte um untersützung, mfg



  • Hallo,

    ich bin mir fast sicher dass du in dem Buch früher oder später auf Schleifen treffen wirst. Die sind dann für sowas super zu gebrauchen!

    for (int i = 0 /* start */; i < Memo1->Lines->Count /* ende */; i++ /* step */)
    {
        // Hier steht das was pro "Step" passieren soll
    }
    

    Wenn du um das was du bereits hast eine solche Schleife baust, könnte das zum gewünschten Erfolg führen ^^.

    mfg, Micha



  • Hm, die IDE kann doch spaltenweise Löschen...



  • Mit schleifen hab ich schon probiert, bringt nicht das gewünschte ergebnis, weil wenn im quellcode eine zahl steht nimmt er die ja auch weg, er soll ja nur die die ersten beiden zeichen löschen (1: ) oder drei zeichen (10:), kann man das nicht über Arrays machen? kann man Ihm sagen nimm die in jeder zeile die ersten 2 oder 3 zeichen weg. hier ein ausschnit von meinem code

    Einlesen.get(Zeichen);
      while (Einlesen.good())
      {
        if (Zeichen=='') Zeichen='\n';  
        Ausgeben.put(Zeichen);
        Einlesen.get(Zeichen);
      }
    


  • so in etwa:

    TStringList* slCode = new TStringList();
    slCode->LoadFromFile(/*Pfad und Dateiname*/);
    int pos;
    for (int i = 0; i < slCode->Count; i++);
    {
    	AnsiString CurLine = slCode->Strings[i];
    	pos = CurLine.AnsiPos(":");
    	if (pos > 0 && pos < 5) // maximal 4-stellige Zeilennummer...
    		CurLine = CurLine.Delete(1, pos);
    	Memo1->Lines->Add(CurLIne);
    }
    

    Aber noch mal der Hinweis darauf, dass die Editor im BCB SPALTENWEISE löschen kann, Du brauchst kein Programm...



  • was ist bcb ? borland c builder? der code hilft mir nicht weiter, bekomm nur fehler beim compilieren.



  • Verwendest Du denn überhaupt den BCB (Borland C++ Builder)?



  • nein verwende microsoft visual c++ habe aber auch dev c++



  • Ja, dann stellt sich mir die Frage, warum Du die Frage im Forum für den BCB stellst?

    Ein Moderator wird deinen Thread gleich ins korrekte Forum verschieben...



  • Dieser Thread wurde von Moderator/in akari aus dem Forum VCL (C++ Builder) 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.



  • Hallo

    So ein Mist, hab erst jetzt gesehen das diesr Thread ja geteilt werden muß... kann bitte ein Mod aus dem MFC-Forum diesen Thread wieder zurückschieben, damit ich ihn richtig teilen kann.

    bis bald
    akari



  • Problem besteht immer noch. Ich komme mit dem quellcode nicht zurecht.



  • Dieser Thread wurde von Moderator/in Unix-Tom aus dem Forum MFC (Visual C++) in das Forum VCL (C++ Builder) verschoben.

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

    Dieses Posting wurde automatisch erzeugt.



  • Hallo,

    es spielt doch keine Rolle welche Umgebung du nutzt! Wenn du es wirklich mittels Programm realisieren willst ist das Prinzip immer das gleiche. Du gehst deinen "Text" zeilenweise durch und suchst pro Zeile nach dem jeweils ersten Vorkommen von ":" .. bis zu dieser Position (einschließlich des ":") schneidest du alles weg und das wars schon.

    mfg, Micha



  • @twice_cube
    Du kannst zum zeilenweisen Einlesen getline verwenden und die Zeilen dann z.Bsp. in ein std::vectorstd::string packen. Danach kannst du diese Strings bearbeiten wie du willst.



  • ich kann damit nix anfangen bitte etwas genauer beschreiben, ich hatte einen ausschnitt von meinem quellcode reingestellt kann vielleicht jmd den so schreiben das es klappt?mit for schleife oder so.



  • Problem besteht immer noch!


Anmelden zum Antworten