Trong tất cả các bài học trước, dữ liệu chúng ta xử lý đều nằm trên RAM và sẽ biến mất ngay khi chương trình kết thúc hoặc mất điện. Để dữ liệu có thể tồn tại bền vững và có thể di chuyển giữa các máy tính khác nhau, chúng ta cần đến Thao tác với Tệp tin (File I/O). Bài viết này sẽ hướng dẫn bạn cách làm chủ việc đọc và ghi dữ liệu dưới cả dạng văn bản và nhị phân.
🎯 Mục tiêu học tập
- Hiểu rõ tầm quan trọng của việc lưu trữ dữ liệu vào File.
- Phân biệt được File văn bản (Text file) và File nhị phân (Binary file).
- Nắm vững các chế độ (Mode) khi mở file:
r, w, a, rb, wb…
- Thành thạo các hàm cơ bản:
fopen, fclose, fprintf, fscanf.
- Làm chủ kỹ thuật đọc/ghi dữ liệu khối với
fread và fwrite cho file nhị phân.
1. Tại sao cần sử dụng File?
Việc sử dụng tệp tin mang lại ba lợi ích cốt lõi:
- Bảo toàn dữ liệu: Dữ liệu không bị mất khi chương trình kết thúc.
- Tiết kiệm thời gian: Thay vì nhập tay một lượng dữ liệu lớn mỗi khi chạy, bạn có thể đọc trực tiếp từ tệp có sẵn.
- Tính di động: Dễ dàng di chuyển tệp dữ liệu giữa các máy tính mà không làm thay đổi cấu trúc nội dung.
2. Các kiểu File trong lập trình C
Ngôn ngữ C hỗ trợ hai loại tệp tin chính:
- File văn bản (Text files – .txt): Lưu trữ dữ liệu dưới dạng ký tự thuần túy, dễ đọc bằng các trình soạn thảo như Notepad nhưng tính bảo mật thấp và chiếm không gian lớn.
- File nhị phân (Binary files – .bin): Lưu trữ dưới dạng mã máy (0 và 1). Loại tệp này bảo mật tốt hơn, chiếm ít dung lượng hơn nhưng con người không thể đọc trực tiếp nếu không có công cụ chuyên dụng.
3. Các chế độ mở File (Modes)
Khi sử dụng hàm fopen(), tham số mode cực kỳ quan trọng vì nó quyết định quyền hạn của bạn đối với tệp đó:
| Mode |
Ý nghĩa |
Nếu tệp không tồn tại |
r / rb |
Mở để đọc (văn bản/nhị phân) |
Trả về NULL |
w / wb |
Mở để ghi (Ghi đè nội dung cũ) |
Tạo tệp mới |
a / ab |
Ghi bổ sung vào cuối tệp |
Tạo tệp mới |
r+ / w+ |
Mở để cả đọc và ghi |
Tùy thuộc vào tiền tố r hoặc w |
4. Thao tác với File văn bản
Để làm việc với file, bạn cần khai báo một con trỏ kiểu FILE *.
Mở và Đóng File
FILE *fptr;
fptr = fopen("program.txt", "w"); // Mở file để ghi
// Xử lý dữ liệu...
fclose(fptr); // Luôn đóng file sau khi dùng xong
Ví dụ: Ghi số vào File
fprintf(fptr, "%d", num); // Tương tự printf nhưng ghi vào file
Ví dụ: Đọc số từ File
fscanf(fptr, "%d", &num); // Tương tự scanf nhưng đọc từ file
5. Thao tác với File nhị phân (fread/fwrite)
File nhị phân thường dùng để lưu các cấu trúc dữ liệu (Struct) một cách nhanh chóng.
Ghi File nhị phân với fwrite()
Cú pháp yêu cầu 4 tham số: Địa chỉ dữ liệu, kích thước, số lượng và con trỏ file.
struct threeNum num = {1, 5, 6};
fwrite(&num, sizeof(struct threeNum), 1, fptr);
Đọc File nhị phân với fread()
fread(&num, sizeof(struct threeNum), 1, fptr);
printf("n1: %d\tn2: %d\tn3: %d", num.n1, num.n2, num.n3);
🚀 Bài tập về nhà
Viết chương trình thực hiện các yêu cầu sau:
- Đọc một file văn bản chứa hỗn hợp: số, chữ cái và ký tự đặc biệt.
- Tách và ghi các con số vào tệp
numbers.txt.
- Tách và ghi các chữ cái vào tệp
letters.txt.
- Tách và ghi các ký tự đặc biệt vào tệp
special.txt.
📝 Tóm tắt: Thao tác File là cầu nối giữa chương trình và bộ nhớ dài hạn. Hãy luôn kiểm tra con trỏ FILE * có bị NULL hay không sau khi mở và đừng quên fclose() để giải phóng tài nguyên hệ thống.
Gợi ý bài tiếp theo: Cấu trúc dữ liệu và Thuật toán cơ bản (Danh sách liên kết). Chúng ta sẽ bước vào thế giới của các thuật toán tối ưu!
Người thực hiện: Nguyễn Đình Tuấn
Email: tuannguyen.aiot@gmail.com | Website: aiots.vn