2016-05-18 13 views
0

Ich habe eine Datei und ich möchte nur die letzte Zeile an die Konsole ausgeben.Suche nach Zeichen vom Ende der Datei mit seekg() C++

Hier sind meine Gedanken darüber, wie ich es tun würde. Verwenden Sie file.seekg(0, ios::end), um mich am Ende der Datei zu setzen.

Dann könnte ich eine Dekrementvariable int decrement = -1; erstellen und verwenden Sie eine while-Schleife

while (joke.peek() != '\n') 
{ 
    decrement--; 

} 

und die Ausgangsposition für meine letzte Zeile erhalten (rückwärts vom Ende).

Mit diesem Wissen, joke.seekg(decrement, ios::end); soll mich zu Beginn der letzten Zeile gesetzt, und unter der Voraussetzung, erklärte ich vorher string input; Ich würde denken, dass

getline(joke, input); 
cout << input << endl; 

ausgeben würde es an die Konsole.

Voll Code

void displayLastLine(ifstream &joke) 
{ 
    string input; 
    int decrement = -1; 


    joke.clear(); 
    joke.seekg(0, ios::end); 


    while (joke.peek() != '\n') 
    { 
     decrement--; 

    } 
    joke.clear(); 

    joke.seekg(decrement, ios::end); 

    getline(joke, input); 
    cout << input << endl; 

} 

Das Problem ist, wenn ich diese Methode für die Datei gehen zu nennen, geschieht nichts. Wenn ich es durchtrete, wird das Dekrement einfach weiter subtrahiert, weit darüber hinaus, wo ein '\n' wäre. Um ein Beispiel für eine Textdatei zu geben, würde es in etwa so aussehen:

Junk

Müll

überspringen Sie diese Zeile

Das ist die Linie, die wir suchen!

Antwort

1
joke.seekg(0, ios::end); 

Dies positioniert die Datei am Ende.

while (joke.peek() != '\n') 

Nun, hier ist das Problem # 1. Wenn Sie sich am Ende der Datei befinden, gibt peek() immer EOF zurück.

decrement--; 

Sie schreiben:

Wenn ich durch sie Schritt, die Abnahme hält nur eine auf Subtrahieren

Nun, was hast du erwartet geschehen, denn das ist das einzige, was ist dass die Schleife funktioniert? Das einzige, was Ihre for Schleife macht, ist 1 von decrement zu subtrahieren. Das passiert also.

Dies ist ein häufiges Problem: Ein Computer macht nur das, was Sie ihm sagen, statt das, was Sie tun sollen.

Obwohl dies nicht optimal ist, ist Ihr fehlender Schritt, dass Sie vor peek()seek() um ein Zeichen zurückgeben müssen. Dann zeigt peek() das Zeichen an der aktuellen Cursorposition an. Dann, seek() um ein weiteres Zeichen zurück, und überprüfen Sie wieder peek(), und so weiter.

Aber das wird immer noch nicht für Sie ausreichen. Die meisten Textdateien enden mit einem Zeilenumbruchzeichen. Das heißt, eine neue Zeile ist das letzte Zeichen in der Datei. Also, selbst wenn Sie die fehlenden seek() hinzufügen, wird in fast allen Fällen, was Ihr Code am Ende tun wird, das letzte Zeichen in der Datei finden, das letzte Zeilenende-Zeichen.

Meine Empfehlung für Sie ist es, für einen Moment aufhören, Code zu schreiben, und stattdessen einen logischen Prozess zu tun, was Sie tun möchten, und beschreiben Sie diesen Prozess in einfachen Worten. Dann, discuss your proposed course of action with your rubber duck. Erst nachdem Ihre Gummiente zustimmt, dass das, was Sie vorschlagen, funktioniert, übersetzen Sie Ihre einfache Sprachbeschreibung in Code.

+0

Fast alle Ihre Punkte sind gültig. Ich beginne jedoch mit meiner Suche bei -1 und starte damit meine Suche mit dem NEXT zum letzten Zeichen. – Podo

+0

Ich werde auch in Zukunft meine Gummiente konsultieren, bevor ich nach SO komme. – Podo

+0

Ich muss meine Augen überprüfen lassen, sorry. Ich schwor, ich sah 'joke.seekg (0, ios :: end);' im Code, mit einer großen fetten Null drin, und nicht -1. Und, -1 hätte den Dateizeiger auf das letzte Zeichen in der Datei gesetzt, nicht auf das vorletzte Zeichen. –

1

peek verschiebt den Dateizeiger nicht, es liest das Zeichen, ohne es zu extrahieren. Sie sehen also ständig denselben Wert (Zeichen) und landen in einer Endlosschleife.

Was würden Sie tun müssen, ist so etwas wie:

while (joke.peek() != '\n') 
{ 
    joke.seek(-1, ios::cur); 
} 

, dass die Eingabeposition am \n setzen würde, die 2. Überlastung der seekg verwenden.

Bitte beachten Sie, dass dies keine perfekte Lösung ist. Sie müssen auf Fehler und Randbedingungen prüfen, aber es erklärt Ihr beobachtetes Verhalten und gibt Ihnen etwas, um anzufangen, Ihren Code zu reparieren.

0

Ihre Schleife dekrementiert eigentlich nur "Dekrement" und verwendet sie nicht, um die nächste Suche durchzuführen.

while (joke.peek() != '\n') 

{ 
    joke.seekg(decrement, std::ios::end); 
    decrement--; 
} 
Verwandte Themen