Giải pháp của Armen là câu trả lời đúng, nhưng tôi nghĩ tôi sẽ đưa ra một giải pháp thay thế dựa trên ý tưởng bộ nhớ đệm của jweyrich. Đối với tốt hơn hoặc tồi tệ hơn, điều này đọc trong toàn bộ tệp lúc xây dựng, nhưng chỉ lưu các vị trí dòng mới (không lưu trữ toàn bộ tệp, vì vậy nó phát tốt với các tệp lớn.) Sau đó, bạn có thể chỉ cần gọi ReadNthLine và nó sẽ ngay lập tức nhảy đến dòng đó và đọc trong một dòng bạn muốn. Mặt khác, điều này chỉ tối ưu nếu bạn muốn chỉ nhận được một phần nhỏ của các dòng tại một thời điểm, và các số dòng không được biết tại thời gian biên dịch.
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;
}
};
Nguồn
2011-09-01 17:03:23
Bạn có thể bọc này trong một vòng lặp và sử dụng một bộ đếm: http://stackoverflow.com/questions/3910326/c-read -file-line-by-line-then-split-each-line-using-the-delimiter/3910610 # 3910610 - Nhưng bạn có thể muốn lưu trữ toàn bộ nội dung tệp trong bộ nhớ để nếu bạn thực hiện nhiều lần tra cứu, nó sẽ là nhanh hơn rất nhiều. – jweyrich