Cách đơn giản, hiệu quả để đọc toàn bộ nội dung file văn bản vào một std::string dùng std::ostringstream và rdbuf().
Thuật toán
Bắt đầu
Mở ifstream f("filename")
Khai báo string str
Nếu file mở thành công:
Tạo ostringstream ss
ss << f.rdbuf() // đọc toàn bộ buffer
str = ss.str()
In str
Kết thúc
Mã nguồn
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main() {
ifstream f("a.txt");
string str;
if (f) {
ostringstream ss;
ss << f.rdbuf();
str = ss.str();
}
cout << str;
return 0;
}
Input (file a.txt)
hi
Output
hi
Phân tích
f.rdbuf()trả về con trỏstreambuf*– buffer nội bộ của stream.operator<<củaostringstreamnạp chồng chostreambuf*– copy toàn bộ dữ liệu hiệu quả.- Không cần vòng lặp, không cần cấp phát buffer thủ công.
Các cách khác
| Phương pháp | Code | Đánh giá |
|---|---|---|
| ostringstream + rdbuf() | Như trên | Ngắn, idiomatic, hiệu quả |
| istreambuf_iterator | string str(istreambuf_iterator<char>(f), {}); | Một dòng, C++11, rất nhanh |
| vector | Xác định size file, resize vector, f.read() | Kiểm soát bộ nhớ, phức tạp hơn |
| C-style FILE* | fseek, ftell, fread | Không khuyến nghị C++ |
Khuyến nghị (C++11/17/20)
// C++11: ngắn gọn nhất
std::string readFile(const std::string& path) {
std::ifstream f(path);
return {std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>()};
}
// C++17: filesystem + string
#include <filesystem>
std::string readFile(const std::filesystem::path& path) {
std::ifstream f(path);
return {std::istreambuf_iterator<char>(f), {}};
}
Lưu ý
- File lớn (hàng GB) – không nên đọc hết vào RAM, dùng memory-map (
mmap/CreateFileMapping) hoặc đọc theo chunk. - File văn bản có BOM/encoding – cần xử lý riêng (UTF-8, UTF-16).