C++ Letzte Zeile einer File auslesen

T_55

Lieutenant
Registriert
Feb. 2013
Beiträge
638
Hallo,

auf der Suche nach einem Schnipsel zum Auslesen der letzten Zeile einer File, bin ich auf folgenden Code gestoßen.
https://stackoverflow.com/questions/11876290/c-fastest-way-to-read-only-last-line-of-text-file

Code:
    std::string filename = "test.csv";
    std::ifstream fin;
    fin.open(filename);
    if(fin.is_open()) 
    {
        fin.seekg(-1,std::ios_base::end); // go to one spot before the EOF
    
        bool keepLooping = true;
        while(keepLooping) 
        {
            char ch;
            fin.get(ch);  // Get current byte's data
    
            if((int)fin.tellg() <= 1) 
            {   // If the data was at or before the 0th byte
                fin.seekg(0);  // The first line is the last line
                keepLooping = false;  // So stop there
            }
            else if(ch == '\n') 
            {   // If the data was a newline
                keepLooping = false;   // Stop at the current position.
            }
            else 
            {   // If the data was neither a newline nor at the 0 byte
                fin.seekg(-2,std::ios_base::cur);  // Move to the front of that data, then to the front of the data before it
            }
        }
        std::string lastLine;
        getline(fin,lastLine);    // Read the current line
        std::cout << "Result: " << lastLine << '\n';     // Display it
        fin.close();
    }

Leider ist die Ausgabe aber immer leer. Habe schon probiert mit und ohne Zeilenumbruch nach der letzten Zeile aber keine Besserung. File und Filename hab ich auch schon überprüft. Ich Kompiliere zu Zeit auf Linux, der Code-Urheber nutzt scheinbar MSVC, das wäre noch der einzige Unterschied der mir aufgefallen ist. Anhand der vielen guten Bewertungen des Codes kann man ja davon ausgehen, dass es bei manchen funktioniert...
Hat jemand eine Idee warum keine Ausgabe kommt?

Gruß
 
Zuletzt bearbeitet:
Code:
#include <cstdio>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;


string get_last_line(const string& fname)
{
   ifstream fh(fname);
   string line, last_line;
   while (getline(fh, line)) {
      if (!line.empty()) last_line = line;
   }
   return last_line;
}


int main()
{
 string fname = "text.txt";
 string ll = get_last_line(fname);
 cout << ll << endl;

}
 
Der "Code" führt aber dazu, dass eine Leerzeile zwischendurch ebenfalls zum Abbruch führt. Es sei denn (und das kann ich leider gerade nicht einschätzen) eine leere Zeile enthält in dieser Interpretation zwar kein echtes Zeichen aber ein Steuerzeichen (Linebreak) und gilt damit nicht als leer.

Nach kurzer Suche bin ich auf diese Implementation gestoßen. Inspiriert vom tail-Command unter Linux. Der Vorteil ist, dass nicht das gesamte File gelesen wird, da dies bei sehr großen Dateien zu einer sehr schlechten Performance führt. Alternativ kannst du natürlich auch wie bereits vorgeschlagen deinen eigenen Code debuggen.
 
Zuletzt bearbeitet:
Danke.

Über diese Anmerkung beim Link bin ich glaube ich auf die Ursache gekommen:
"This does not work for me since textfiles should end with a new line character and many editors insert that character automatically. – phinz Jan 19 at 9:24 "

Also das Problem scheint daran zu liegen, dass manche Texteditoren automatisch an jede File eine "new line" ranhängen".
Wenn ich ein File von Windows hole oder ein File per Program selbst fülle ist tatsächlich alles ok.

Insofern wohl eine Eigenheit von manchen Texteditoren bzw wohl speziell vom POSIX Standard (https://stackoverflow.com/questions/729692/why-should-text-files-end-with-a-newline) so genau verstehe ich das nicht aber gut die Ursache ist gefunden.

@Drarlor: Danke die Implementation schau ich auch nochmal an.


Danke auch @blöderidiot, ich habe allerdings tatsächlich manche Files mit mehreren GB da ist es dann nicht so effizient alles zu iterieren, aber schön kurz der Code und für kleinere Dateien gut zu gebrauchen.
 
Zuletzt bearbeitet:
Zurück
Oben