Eine gute Lösung ist das Lesen der Datei von Anfang bis zur gewünschten Position (Antwort von @Chet Simpson). Wenn Sie eine Optimierung wünschen (z. B. sehr große Datei, irgendwo in der Mitte, typische Zeilen eher kurz), können Sie die Datei rückwärts lesen. Dies funktioniert jedoch nur mit Dateien, die im Binärmodus geöffnet werden (jede Datei auf Unix-ähnlichen Plattformen; öffnen Sie die Datei mit dem Parameter ios_base::binary
unter Windows).
Der Algorithmus geht wie folgt:
- Zurück ein paar Bytes in der Datei
- Lesen Sie den wenige Bytes
- Wenn es eine ist End-of-line gibt, ist der Rest einfach
- Ansonsten wiederholen
-Code (getestet unter Windows):
std::string GetSurroundingLine(std::istream& f, std::istream::pos_type start_pos)
{
std::istream::pos_type prev_pos = start_pos;
std::istream::pos_type pos;
char buffer[40]; // typical line length, so typical iteration count is 1
std::istream::pos_type size = sizeof(buffer);
// Look for the beginning of the line that includes the given position
while (true)
{
// Move back 40 bytes from prev_pos
if (prev_pos < size)
pos = 0;
else
pos = prev_pos - size;
f.seekg(pos);
// Read 40 bytes
f.read(buffer, prev_pos - pos);
if (!f)
throw;
// Look for a newline byte, which terminates previous line
int eol_pos;
for (eol_pos = sizeof(buffer) - 1; eol_pos >= 0; --eol_pos)
if (buffer[eol_pos] == '\n')
break;
// If found newline or got to beginning of file - done looking
if (eol_pos >= 0 || pos == (std::istream::pos_type)0)
{
pos += eol_pos + 1;
break;
}
}
// Position the read pointer
f.seekg(pos);
// Read the line
std::string s;
std::getline(f, s, '\n');
return s;
}
Edit: Auf Windows-ähnlichen Plattformen, wo das Ende der Zeile mit \r\n
markiert ist, enthält die Ausgabezeichenfolge das zusätzliche Zeichen \r
(es sei denn, es gibt kein End-of-Line- Linie am Ende der Datei), die Sie wegwerfen können.
Suchen Sie nach dem Offset, den Sie haben, und gehen Sie dann rückwärts, bis Sie einen Zeilenumbruch finden. Dann lies bis zum nächsten Zeilenumbruch. Einfach. –
Gibt es eine Möglichkeit, eine ganze Zeile auf einmal zu lesen, ohne von einer Zeile zur nächsten zu lesen? – Meir
Eine ganze Zeile gleichzeitig lesen * liest * von einem Zeilenende zum nächsten. –