c ++ schnellste Möglichkeit, nur die letzte Zeile der Textdatei zu lesen?

7

Ich möchte nur die letzte Zeile einer Textdatei lesen (ich bin auf UNIX, kann Boost verwenden). Alle Methoden, die ich kenne, erfordern das Durchsuchen der gesamten Datei, um die letzte Zeile zu erhalten, die überhaupt nicht effizient ist. Gibt es einen effizienten Weg, nur die letzte Zeile zu bekommen?

Außerdem muss das so robust sein, dass es auch funktioniert, wenn die betreffende Textdatei ständig von einem anderen Prozess angehängt wird.

    
user788171 09.08.2012, 03:16
quelle

6 Antworten

15

Verwenden Sie seekg, um zum Ende der Datei zu springen, und lesen Sie dann zurück, bis Sie den ersten Zeilenumbruch gefunden haben. Unten ist ein Beispielcode von der Spitze meines Kopfes mit MSVC.

%Vor%

Und unten ist eine Testdatei. Es ist erfolgreich mit leeren, einzeiligen und mehrzeiligen Daten in der Textdatei.

%Vor%     
derpface 09.08.2012, 05:53
quelle
4

Springe zum Ende und lese Blöcke rückwärts, bis du die Kriterien für eine Linie gefunden hast. Wenn der letzte Block nicht mit einer Linie "endet", müssen Sie wahrscheinlich auch versuchen, vorwärts zu scannen (vorausgesetzt, dass eine wirklich lange Linie in einer aktiv an die Datei angehängt ist).

    
Will Hartung 09.08.2012 03:20
quelle
1

Sie können seekg () benutzen, um zum Ende der Datei zu springen, und rückwärts lesen, der Pseudo-Code ist wie folgt:

%Vor%     
carter2000 09.08.2012 03:33
quelle
1

Obwohl die Antwort von derpface definitiv korrekt ist, liefert sie oft unerwartete Ergebnisse. Der Grund dafür ist, dass zumindest auf meinem Betriebssystem (Mac OS X 10.9.5) viele Texteditoren ihre Dateien mit einem "End Line" -Zeichen beenden.

Zum Beispiel, wenn ich vim öffne, tippe nur das einzelne Zeichen 'a' (keine Rückkehr), und speichere, die Datei enthält nun (in hexadezimal):

%Vor%

Wobei 61 der Buchstabe 'a' und 0A ein Zeilenendezeichen ist.

Dies bedeutet, dass der Code von derpface eine leere Zeichenfolge für alle Dateien zurückgibt, die von einem solchen Texteditor erstellt wurden.

Obwohl ich mir durchaus vorstellen kann, dass Fälle, in denen eine mit einer Endzeile abgeschlossene Datei die leere Zeichenfolge zurückgeben sollte, wäre es für normale Textdateien besser, das letzte Zeichen der Endzeile zu ignorieren. Wenn die Datei durch ein 'end line' Zeichen beendet wird, ignorieren wir sie ordnungsgemäß und wenn die Datei nicht durch ein 'end line' Zeichen beendet wird, müssen wir sie nicht überprüfen.

Mein Code zum Ignorieren des letzten Zeichens der Eingabedatei ist:

%Vor%

Was wird ausgegeben:

%Vor%

In der einzelnen 'a' Datei.

EDIT: Die Zeile if((int)fin.tellg() <= 0){ verursacht tatsächlich Probleme, wenn die Datei zu groß ist (& gt; 2GB), weil tellg nicht nur die Anzahl der Zeichen vom Anfang der Datei zurückgibt ( tellg () -Funktion geben falsche Dateigröße? ). Es kann besser sein, für den Anfang der Datei fin.tellg()==tellgValueForStartOfFile und für Fehler fin.tellg()==-1 separat zu testen. Die tellgValueForStartOfFile ist wahrscheinlich 0, aber ein besserer Weg wäre sicher:

%Vor%     
Joost Huizinga 15.10.2014 00:52
quelle
0

Ich habe auch mit dem Problem gekämpft, weil ich den Code von uberwulu durchgelaufen bin und auch eine Leerzeile bekommen habe. Hier ist was ich gefunden habe. Ich verwende die folgende .csv-Datei als Beispiel:

%Vor%

Um die Befehle im Code zu verstehen, beachten Sie bitte die folgenden Positionen und die entsprechenden Zeichen. (Loc, char): ... (63, '3'), (64, '5'), (65, -), (66, '\ n'), (EOF, -).

%Vor%     
Gary Yang 10.09.2014 20:01
quelle
0

Ursprünglich sollte dies der letzte Syslog-Eintrag sein. Da das letzte Zeichen vor dem EOF '\n' ist, suchen wir zurück, um das nächste Vorkommen von '\n' zu finden, und speichern dann die Zeile in einer Zeichenkette.

%Vor%     
alexandros 30.05.2016 09:23
quelle

Tags und Links