Хорошее решение - это чтение файла с самого начала до желаемой позиции (ответ от @Chet Simpson). Если вы хотите оптимизировать (например, очень большой файл, положение где-то посередине, типичные строки довольно короткие), вы можете прочитать файл назад. Однако это работает только с файлами, открытыми в двоичном режиме (любой файл на unix-подобных платформах, открыть файл с параметром ios_base::binary
в Windows).
алгоритм выглядит следующим образом:
- Вернитесь несколько байт в файле
- Прочитайте несколько байт
- Если есть символ конца строки есть, остальное легко
- в противном случае повторите
код (проверено на 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;
}
Редактирование: на платформах под Windows, где конец строки отмечен \r\n
, так как вы должны использовать двоичный режим, выходная строка будет содержать дополнительный символ \r
(если только нет конца, строка в конце файла), которую вы можете выбросить.
Ищите подходящее вам смещение, а затем идите назад, пока не найдете новую строку. Затем читайте до следующей новой строки. Легко. –
Есть ли способ прочитать целую строку сразу, не читая от одной новой строки до следующей? – Meir
Чтение всей строки сразу * * считывание с одной новой строки на другую. –