Xử lý File trong C: Đọc ghi File văn bản và nhị phân
Khám phá sức mạnh xử lý file trong C: đọc ghi văn bản, nhị phân, quản lý file pointer và các kỹ thuật lưu trữ dữ liệu bền vững.
•19 tháng 10, 2025

Tóm tắt kiến thức
Xử lý file là kỹ năng thiết yếu để tạo ra các ứng dụng thực tế. Hiểu rõ cách đọc ghi file văn bản và nhị phân, quản lý file pointer và xử lý lỗi sẽ giúp bạn xây dựng các chương trình có thể lưu trữ và khôi phục dữ liệu.
Xử lý file là một phần quan trọng trong lập trình, cho phép lưu trữ và truy xuất dữ liệu một cách bền vững. Khả năng làm việc với file giúp tạo ra các ứng dụng thực tế có thể lưu trữ dữ liệu, cấu hình và trao đổi thông tin với các chương trình khác.
Quảng cáo giúp chúng tôi duy trì trang web này
Tổng quan về xử lý file
Khái niệm file
File là một tập hợp dữ liệu được lưu trữ trên thiết bị lưu trữ (ổ cứng, USB, v.v.). File cho phép dữ liệu tồn tại ngay cả khi chương trình kết thúc.
Các loại file
File văn bản (Text File): Chứa dữ liệu dạng văn bản, có thể đọc được bằng text editor
- Dễ đọc và chỉnh sửa
- Sử dụng ký tự newline để xuống dòng
- Phù hợp cho cấu hình, log, dữ liệu người dùng
File nhị phân (Binary File): Chứa dữ liệu dạng nhị phân, không thể đọc trực tiếp
- Hiệu quả hơn về mặt lưu trữ
- Giữ nguyên cấu trúc dữ liệu gốc
- Phù hợp cho hình ảnh, âm thanh, database
Mở và đóng file
Khai báo con trỏ file
FILE *con_trỏ_file;Hàm fopen() - Mở file
FILE *fopen(const char *filename, const char *mode);Các chế độ mở file
| Mode | Mô tả |
|---|---|
| "r" | Mở để đọc (file phải tồn tại) |
| "w" | Mở để ghi (tạo file mới hoặc ghi đè) |
| "a" | Mở để ghi thêm vào cuối file |
| "r+" | Mở để đọc và ghi |
| "w+" | Tạo file mới để đọc và ghi |
| "a+" | Mở để đọc và ghi thêm vào cuối |
Ví dụ cơ bản:
#include <stdio.h>
int main() {
FILE *file;
// Mở file để ghi
file = fopen("example.txt", "w");
if (file == NULL) {
printf("Khong the mo file!\n");
return 1;
}
// Ghi dữ liệu vào file
fprintf(file, "Xin chao, day la file vi du!\n");
fprintf(file, "Chuong trinh C xu ly file.\n");
// Đóng file
fclose(file);
printf("Da ghi file thanh cong!\n");
return 0;
}Ghi file văn bản
fprintf() - Ghi có định dạng
#include <stdio.h>
int main() {
FILE *file = fopen("student.txt", "w");
if (file == NULL) {
printf("Khong the tao file!\n");
return 1;
}
// Ghi thông tin sinh viên
fprintf(file, "=== DANH SACH SINH VIEN ===\n");
fprintf(file, "Ho ten: Nguyen Van A\n");
fprintf(file, "Tuoi: %d\n", 20);
fprintf(file, "Diem: %.2f\n", 8.5);
fprintf(file, "Lop: %s\n", "CNTT01");
fclose(file);
printf("Da ghi thong tin sinh vien vao file!\n");
return 0;
}fputs() - Ghi chuỗi
#include <stdio.h>
int main() {
FILE *file = fopen("lines.txt", "w");
if (file == NULL) {
printf("Khong the tao file!\n");
return 1;
}
fputs("Dong thu nhat\n", file);
fputs("Dong thu hai\n", file);
fputs("Dong thu ba\n", file);
fclose(file);
printf("Da ghi cac dong vao file!\n");
return 0;
}fputc() - Ghi ký tự
#include <stdio.h>
int main() {
FILE *file = fopen("characters.txt", "w");
if (file == NULL) {
printf("Khong the tao file!\n");
return 1;
}
char ch = 'A';
for (int i = 0; i < 26; i++) {
fputc(ch + i, file);
fputc(' ', file);
}
fclose(file);
printf("Da ghi bang chu cai vao file!\n");
return 0;
}Đọc file văn bản
fscanf() - Đọc có định dạng
#include <stdio.h>
int main() {
FILE *file = fopen("student.txt", "r");
if (file == NULL) {
printf("Khong the mo file!\n");
return 1;
}
char name[50], class[20];
int age;
float grade;
// Bỏ qua dòng tiêu đề
char buffer[100];
fgets(buffer, sizeof(buffer), file);
// Đọc thông tin
fscanf(file, "Ho ten: %[^\n]", name);
fscanf(file, "Tuoi: %d", &age);
fscanf(file, "Diem: %f", &grade);
fscanf(file, "Lop: %s", class);
printf("Thong tin sinh vien:\n");
printf("Ho ten: %s\n", name);
printf("Tuoi: %d\n", age);
printf("Diem: %.2f\n", grade);
printf("Lop: %s\n", class);
fclose(file);
return 0;
}fgets() - Đọc dòng
#include <stdio.h>
int main() {
FILE *file = fopen("lines.txt", "r");
if (file == NULL) {
printf("Khong the mo file!\n");
return 1;
}
char line[100];
printf("Noi dung file:\n");
while (fgets(line, sizeof(line), file) != NULL) {
printf("%s", line);
}
fclose(file);
return 0;
}fgetc() - Đọc ký tự
#include <stdio.h>
int main() {
FILE *file = fopen("characters.txt", "r");
if (file == NULL) {
printf("Khong the mo file!\n");
return 1;
}
char ch;
printf("Noi dung file:\n");
while ((ch = fgetc(file)) != EOF) {
printf("%c", ch);
}
fclose(file);
return 0;
}Ghi file nhị phân
fwrite() - Ghi dữ liệu nhị phân
#include <stdio.h>
typedef struct {
char name[50];
int age;
float salary;
} Employee;
int main() {
Employee emp = {"Nguyen Van A", 30, 15000000};
FILE *file = fopen("employee.bin", "wb");
if (file == NULL) {
printf("Khong the tao file!\n");
return 1;
}
// Ghi struct vào file nhị phân
fwrite(&emp, sizeof(Employee), 1, file);
fclose(file);
printf("Da ghi struct vao file nhi phan!\n");
return 0;
}Ghi mảng vào file nhị phân
#include <stdio.h>
int main() {
int numbers[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int n = sizeof(numbers) / sizeof(numbers[0]);
FILE *file = fopen("numbers.bin", "wb");
if (file == NULL) {
printf("Khong the tao file!\n");
return 1;
}
// Ghi mảng vào file
fwrite(numbers, sizeof(int), n, file);
fclose(file);
printf("Da ghi mang vao file nhi phan!\n");
return 0;
}Đọc file nhị phân
fread() - Đọc dữ liệu nhị phân
#include <stdio.h>
typedef struct {
char name[50];
int age;
float salary;
} Employee;
int main() {
Employee emp;
FILE *file = fopen("employee.bin", "rb");
if (file == NULL) {
printf("Khong the mo file!\n");
return 1;
}
// Đọc struct từ file nhị phân
fread(&emp, sizeof(Employee), 1, file);
printf("Thong tin nhan vien:\n");
printf("Ten: %s\n", emp.name);
printf("Tuoi: %d\n", emp.age);
printf("Luong: %.0f\n", emp.salary);
fclose(file);
return 0;
}Đọc mảng từ file nhị phân
#include <stdio.h>
int main() {
int numbers[10];
int n = 10;
FILE *file = fopen("numbers.bin", "rb");
if (file == NULL) {
printf("Khong the mo file!\n");
return 1;
}
// Đọc mảng từ file
fread(numbers, sizeof(int), n, file);
printf("Mang doc tu file:\n");
for (int i = 0; i < n; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
fclose(file);
return 0;
}Di chuyển con trỏ file
fseek() - Di chuyển đến vị trí cụ thể
#include <stdio.h>
int main() {
FILE *file = fopen("seek_example.txt", "w");
if (file == NULL) {
printf("Khong the tao file!\n");
return 1;
}
// Ghi dữ liệu ban đầu
fprintf(file, "1234567890");
fclose(file);
// Mở file để đọc
file = fopen("seek_example.txt", "r");
// Di chuyển đến vị trí thứ 5
fseek(file, 5, SEEK_SET);
char ch = fgetc(file);
printf("Ky tu tai vi tri 5: %c\n", ch);
// Di chuyển 2 vị trí từ vị trí hiện tại
fseek(file, 2, SEEK_CUR);
ch = fgetc(file);
printf("Ky tu tai vi tri 7: %c\n", ch);
// Di chuyển đến cuối file
fseek(file, -1, SEEK_END);
ch = fgetc(file);
printf("Ky tu cuoi cung: %c\n", ch);
fclose(file);
return 0;
}ftell() - Lấy vị trí hiện tại
#include <stdio.h>
int main() {
FILE *file = fopen("seek_example.txt", "r");
if (file == NULL) {
printf("Khong the mo file!\n");
return 1;
}
printf("Vi tri ban dau: %ld\n", ftell(file));
fseek(file, 5, SEEK_SET);
printf("Vi tri sau khi seek: %ld\n", ftell(file));
char ch = fgetc(file);
printf("Vi tri sau khi doc 1 ky tu: %ld\n", ftell(file));
fclose(file);
return 0;
}rewind() - Về đầu file
#include <stdio.h>
int main() {
FILE *file = fopen("seek_example.txt", "r");
if (file == NULL) {
printf("Khong the mo file!\n");
return 1;
}
// Di chuyển đến giữa file
fseek(file, 5, SEEK_SET);
printf("Vi tri: %ld\n", ftell(file));
// Về đầu file
rewind(file);
printf("Vi tri sau rewind: %ld\n", ftell(file));
fclose(file);
return 0;
}Kiểm tra lỗi file
feof() - Kiểm tra cuối file
#include <stdio.h>
int main() {
FILE *file = fopen("lines.txt", "r");
if (file == NULL) {
printf("Khong the mo file!\n");
return 1;
}
char line[100];
int lineCount = 0;
while (!feof(file)) {
if (fgets(line, sizeof(line), file) != NULL) {
lineCount++;
printf("Dong %d: %s", lineCount, line);
}
}
printf("Tong so dong: %d\n", lineCount);
fclose(file);
return 0;
}ferror() - Kiểm tra lỗi
#include <stdio.h>
int main() {
FILE *file = fopen("nonexistent.txt", "r");
if (file == NULL) {
printf("Khong the mo file!\n");
return 1;
}
char ch;
while ((ch = fgetc(file)) != EOF) {
printf("%c", ch);
if (ferror(file)) {
printf("Co loi khi doc file!\n");
break;
}
}
fclose(file);
return 0;
}Gộp nội dung file
#include <stdio.h>
int main() {
FILE *file1, *file2, *merged;
char ch;
// Mở các file
file1 = fopen("file1.txt", "r");
file2 = fopen("file2.txt", "r");
merged = fopen("merged.txt", "w");
if (file1 == NULL || file2 == NULL || merged == NULL) {
printf("Khong the mo file!\n");
return 1;
}
// Gộp nội dung file1
while ((ch = fgetc(file1)) != EOF) {
fputc(ch, merged);
}
// Thêm nội dung file2
while ((ch = fgetc(file2)) != EOF) {
fputc(ch, merged);
}
fclose(file1);
fclose(file2);
fclose(merged);
printf("Da gop noi dung 2 file thanh cong!\n");
return 0;
}Sao chép file
#include <stdio.h>
int main() {
FILE *source, *destination;
char ch;
source = fopen("source.txt", "r");
destination = fopen("copy.txt", "w");
if (source == NULL || destination == NULL) {
printf("Khong the mo file!\n");
return 1;
}
while ((ch = fgetc(source)) != EOF) {
fputc(ch, destination);
}
fclose(source);
fclose(destination);
printf("Da sao chep file thanh cong!\n");
return 0;
}Ví dụ thực hành
1. Quản lý danh sách sinh viên với file
#include <stdio.h>
#include <string.h>
typedef struct {
int id;
char name[50];
float grade;
int age;
} Student;
void saveStudents(Student students[], int n) {
FILE *file = fopen("students.txt", "w");
if (file == NULL) {
printf("Khong the tao file!\n");
return;
}
fprintf(file, "%d\n", n);
for (int i = 0; i < n; i++) {
fprintf(file, "%d %s %.2f %d\n",
students[i].id, students[i].name,
students[i].grade, students[i].age);
}
fclose(file);
printf("Da luu danh sach sinh vien vao file!\n");
}
int loadStudents(Student students[]) {
FILE *file = fopen("students.txt", "r");
if (file == NULL) {
printf("Khong the mo file!\n");
return 0;
}
int n;
fscanf(file, "%d", &n);
for (int i = 0; i < n; i++) {
fscanf(file, "%d %s %f %d",
&students[i].id, students[i].name,
&students[i].grade, &students[i].age);
}
fclose(file);
printf("Da tai danh sach sinh vien tu file!\n");
return n;
}
void displayStudents(Student students[], int n) {
printf("\n=== DANH SACH SINH VIEN ===\n");
for (int i = 0; i < n; i++) {
printf("ID: %d, Ten: %s, Diem: %.2f, Tuoi: %d\n",
students[i].id, students[i].name,
students[i].grade, students[i].age);
}
}
int main() {
Student students[100];
int n = 0;
int choice;
do {
printf("\n=== MENU ===\n");
printf("1. Nhap sinh vien\n");
printf("2. Hien thi danh sach\n");
printf("3. Luu vao file\n");
printf("4. Tai tu file\n");
printf("5. Thoat\n");
printf("Chon: ");
scanf("%d", &choice);
switch (choice) {
case 1:
if (n < 100) {
printf("Nhap thong tin sinh vien %d:\n", n + 1);
printf("ID: ");
scanf("%d", &students[n].id);
printf("Ten: ");
scanf(" %[^\n]", students[n].name);
printf("Diem: ");
scanf("%f", &students[n].grade);
printf("Tuoi: ");
scanf("%d", &students[n].age);
n++;
} else {
printf("Danh sach da day!\n");
}
break;
case 2:
displayStudents(students, n);
break;
case 3:
saveStudents(students, n);
break;
case 4:
n = loadStudents(students);
break;
case 5:
printf("Tam biet!\n");
break;
default:
printf("Lua chon khong hop le!\n");
}
} while (choice != 5);
return 0;
}2. Ghi/đọc struct vào file nhị phân
#include <stdio.h>
#include <string.h>
typedef struct {
char title[100];
char author[50];
int pages;
float price;
} Book;
void saveBooks(Book books[], int n) {
FILE *file = fopen("books.bin", "wb");
if (file == NULL) {
printf("Khong the tao file!\n");
return;
}
// Ghi số lượng sách
fwrite(&n, sizeof(int), 1, file);
// Ghi danh sách sách
fwrite(books, sizeof(Book), n, file);
fclose(file);
printf("Da luu %d quyen sach vao file nhi phan!\n", n);
}
int loadBooks(Book books[]) {
FILE *file = fopen("books.bin", "rb");
if (file == NULL) {
printf("Khong the mo file!\n");
return 0;
}
int n;
fread(&n, sizeof(int), 1, file);
fread(books, sizeof(Book), n, file);
fclose(file);
printf("Da tai %d quyen sach tu file nhi phan!\n", n);
return n;
}
void displayBooks(Book books[], int n) {
printf("\n=== DANH SACH SACH ===\n");
for (int i = 0; i < n; i++) {
printf("Ten sach: %s\n", books[i].title);
printf("Tac gia: %s\n", books[i].author);
printf("So trang: %d\n", books[i].pages);
printf("Gia: %.0f VND\n", books[i].price);
printf("--------------------\n");
}
}
int main() {
Book books[50];
int n = 0;
// Thêm một số sách mẫu
strcpy(books[0].title, "Lap trinh C");
strcpy(books[0].author, "Nguyen Van A");
books[0].pages = 300;
books[0].price = 150000;
n++;
strcpy(books[1].title, "Cau truc du lieu");
strcpy(books[1].author, "Tran Thi B");
books[1].pages = 400;
books[1].price = 200000;
n++;
// Lưu vào file
saveBooks(books, n);
// Tải lại từ file
Book loadedBooks[50];
int loadedCount = loadBooks(loadedBooks);
// Hiển thị
displayBooks(loadedBooks, loadedCount);
return 0;
}Tổng kết
Xử lý file là kỹ năng thiết yếu để tạo ra các ứng dụng thực tế có thể lưu trữ và khôi phục dữ liệu.
Lưu ý quan trọng về xử lý file
- Luôn đóng file: Sử dụng fclose() để tránh memory leak
- Kiểm tra lỗi: Luôn kiểm tra kết quả fopen() trước khi sử dụng
- File modes: Hiểu rõ sự khác biệt giữa "r", "w", "a"
- Buffer flush: Sử dụng fflush() khi cần đảm bảo dữ liệu được ghi ngay
Best Practices
- Luôn kiểm tra file pointer trước khi thao tác
- Sử dụng binary mode cho dữ liệu struct
- Kiểm tra EOF và lỗi khi đọc file
- Sử dụng fseek() để di chuyển trong file hiệu quả
- Backup dữ liệu quan trọng trước khi ghi đè
Với những kiến thức này, bạn đã sẵn sàng để xây dựng các ứng dụng có thể lưu trữ dữ liệu bền vững và tạo nền tảng cho các hệ thống quản lý dữ liệu phức tạp!
Last updated on
Edit on GitHubCấu trúc điều khiển trong C: Làm chủ if-else, switch và vòng lặp for, while
Khám phá các cấu trúc điều khiển cốt lõi trong C: câu lệnh điều kiện if-else, switch-case, và các vòng lặp để tạo logic chương trình mạnh mẽ.
Hàm trong C: Bí quyết viết code module hóa và tái sử dụng
Khám phá sức mạnh của hàm trong C: cách định nghĩa, gọi hàm, truyền tham số, giá trị trả về, và kỹ thuật đệ quy để tạo code sạch và tái sử dụng.