Решение Армена - правильный ответ, но я подумал, что выброшу альтернативу, основанную на идее кэширования jweyrich. К лучшему или к худшему, это читает весь файл при создании, но сохраняет только позиции новой строки (не сохраняет весь файл, поэтому он хорошо работает с массивными файлами.) Затем вы можете просто вызвать ReadNthLine, и он сразу же перейти к этой строке и прочитать в той строке, которую вы хотите. С другой стороны, это оптимально, только если вы хотите получать только часть строк за раз, а номера строк не известны во время компиляции.
class TextFile {
std::ifstream file_stream;
std::vector<std::ifstream::streampos> linebegins;
TextFile& operator=(TextFile& b) = delete;
public;
TextFile(std::string filename)
:file_stream(filename)
{
//this chunk stolen from Armen's,
std::string s;
//for performance
s.reserve(some_reasonable_max_line_length);
while(file_stream) {
linebegins.push_back(file_stream.tellg());
std::getline(file_stream, s);
}
}
TextFile(TextFile&& b)
:file_stream(std::move(b.file_stream)),
:linebegins(std::move(b.linebegins))
{}
TextFile& operator=(TextFile&& b)
{
file_stream = std::move(b.file_stream);
linebegins = std::move(b.linebegins);
}
std::string ReadNthLine(int N) {
if (N >= linebegins.size()-1)
throw std::runtime_error("File doesn't have that many lines!");
std::string s;
// clear EOF and error flags
file_stream.clear();
file_stream.seekg(linebegins[N]);
std::getline(file_stream, s);
return s;
}
};