Dobrym rozwiązaniem jest czytanie pliku od początku aż do żądanej pozycji (Odpowiedź @Chet Simpson). Jeśli potrzebujesz optymalizacji (np. Bardzo duży plik, położenie gdzieś pośrodku, typowe linie raczej krótkie), możesz odczytać plik do tyłu. Działa to jednak tylko w przypadku plików otwartych w trybie binarnym (dowolny plik na platformach podobnych do systemu Unix, otwórz plik z parametrem ios_base::binary
w systemie Windows).
Algorytm jest następujący:
- cofnąć się kilka bajtów w pliku
- Przeczytaj kilka bajtów
- Jeśli jest koniec-linii tam, reszta jest prosta
- W przeciwnym razie powtórzyć
kod (testowane na 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;
}
Edytuj: Na platformach podobnych do systemu Windows, gdzie koniec linii jest oznaczony przez \r\n
, ponieważ musisz użyć trybu binarnego, ciąg wyjściowy będzie zawierał dodatkowy znak \r
(chyba że nie ma końca). linia na końcu pliku), którą można wyrzucić.
Odszukaj przesunięcie, które masz, a następnie cofaj się, aż znajdziesz nowy znak. Następnie przeczytaj do następnego wpisu. Łatwo. –
Czy istnieje sposób na odczytanie całej linii naraz, bez czytania od jednej linii do drugiej? – Meir
Czytanie całej linii na raz * to * czytanie z jednego nowego wiersza do następnego. –