1.Con trỏ thao tác với tập tin

Để thực hiện một thao tác mở hay đóng một tập tin ta cần thực hiện thông qua con trỏ.

Con trỏ này sẽ được trỏ đến một cấu trúc chứa thông tin của tập tin cần thao tác. Các thông tin này có thể là:

  • Tên tập tin
  • Địa chỉ tập tin
  • Chế độ làm việc với tập tin
  • Trạng thái của tập tin

Cú pháp khai báo con trỏ tập tin:

FILE *fp;

Trong đó:

  • FILE là kiểu dữ liệu tập tin
  • Fp là tên con trỏ mang kiểu dữ liệu tập tin (ta hoàn toàn có thể đặt tên khác)

2.Mở và đóng một tập tin văn bản

Để thực hiện việc mở một tập tin văn bản, ta sử dụng hàm fopen với cú pháp sau:

FILE *fopen(const char *filename, "mode");

Trong đó:

  • Con trỏ char *filename là địa chỉ của tập tin cần mở
  • Mode là chế độ mở

Có rất nhiều chế độ (Mode) khi ta mở một tập tin văn bản, dưới đây tôi sẽ liệt kê ra một số chế độ thường xuyên được sử dụng khi mở một tập tin văn bản.

Mode Chức năng
r Mở một tập tin văn bản để đọc
w Tạo một tập tin văn bản để ghi
a Nối vào một tập tin văn bản
r+ Mở một tập tin văn bản để đọc/ghi
w+ Tạo một tập tin văn bản để đọc/ghi
a+f Nối hoặc tạo một tập tin văn bản để đọc/ghi

Ví dụ dưới đây, tôi sẽ mở một tập tin văn bản laptrinhtudau.txt tại thư mục E:\laptrinhtudau.txt và đọc nội dung trong tập tin này, sau đó hiển thị toàn bộ nội dung có trong tập tin ra màn hình:

  1. Nội dung trong có trong file laptrinhtudau.txt:

  1. Chương trình mở và hiển thị ra nội dung trong file laptrinhtudau.txt:
#include <stdio.h>
int main(){
    //tao con tro kieu file
    FILE *fp;
    //mo mot tap tin voi mode r de doc file van ban
    fp = fopen("E:\laptrinhtudau.txt ", "r");
    //thuc hien duyet tung ky tu co trong tep tin vua mo
    char ch;
    while (true) {
        //doc tung ky tu voi ham getc
        ch = fgetc(fp); 
        // kiem tra ket thuc file
        if (ch == EOF){
            break;
        } 
        
        printf("%c", ch);
    }
    //dong tap tin
    fclose(fp);
}
Xin chao, day la website laptrinhtudau.com!

Sử dụng với mode r+ cho việc mở tập tin trên tôi cũng nhận được kết quả tương tự. Tuy nhiên mode r mode r+ có sự khác biệt với nhau khi thao tác mở một tập tin để đọc.

Trong khi r chỉ mở các tập tin đã được tạo và đã tồn tại thì r+ sẽ tìm và mở một tập tin kể cả chúng chưa được tạo và chưa tồn tại (r+ sẽ tự động tạo ra tập tin cần mở trong trường hợp tập tin chưa tồn tại)

Chú ý: Sau khi mở và thao tác với tập tin xong ta cần sử dụng hàm fclose(fp) để thực hiện đóng tập tin lại. Thao tác đóng này là hết sức cần thiết!

Trong trường hợp ta muốn kết thúc tất cả tập tin đang mở ta sẽ sử dụng hàm fcloseall();

3.Mở và đóng một tập tin nhị phân

Cú pháp để mở một tập tin nhị phân cũng tương tự như việc mở một tập tin văn bản, tuy nhiên chế độ mở (Mode) sẽ được thay đổi so với mở một tập tin văn bản:

FILE *fopen(const char *filename, "mode");

Trong đó:

  • Con trỏ char *filename là địa chỉ của tập tin cần mở
  • Mode là chế độ mở

Có rất nhiều chế độ (Mode) khi ta mở một tập tin nhị phân, dưới đây tôi sẽ liệt kê ra một số chế độ thường xuyên được sử dụng khi mở một tập tin nhị phân.

Mode Chức năng
rb Mở một tập tin nhị phân để đọc
wb Tạo một tập tin nhị phân để ghi
ab Nối vào một tập tin nhị phân
r+b Mở một tập tin nhị phân để đọc/ghi
w+b Tạo một tập tin nhị phân để đọc/ghi
a+b Nối hoặc tạo một tập tin nhị phân để đọc/ghi

Ở ví dụ tiếp theo này, tôi sẽ mở file ngaysinh.bin tại thư mục E:\ngaysinh.bin và thực hiện ghi dữ liệu có kiểu struct vào file nhị phân ngaysinh.bin bằng hàm fwrite() sau đó tôi thực hiện việc đọc dữ liệu trong file này bằng hàm fread().

Chương trình sử dụng hàm fwrite() để ghi dữ liệu vào file ngaysinh.bin

#include <stdio.h>
#include <stdlib.h>
struct ngaysinh
{
   int ngay;
   int thang;
   int nam;
};
int main()
{
    //tao struct ngaysinh n1
    struct ngaysinh n1;
    //tao con tro file
    FILE *fp;
    //mo file ngaysinh.bin voi che do wb de viet file nhi phan
    fp = fopen("E:\ngaysinh.bin","wb");
    //them du lieu vao struct
    n1.ngay = 11;
    n1.thang = 9;
    n1.nam = 2021;
    //viet du lieu tren vao file ngaysinh.bin
    fwrite(&n1, sizeof(struct ngaysinh), 1, fp); 
    //mo file voi che do rb de doc file nhi phan
    fp = fopen("E:\ngaysinh.bin","rb");
    fread(&n1, sizeof(struct ngaysinh), 1, fp); 
    //hien thi du lieu trong file
    printf("Ngay: %d\tThang: %d\tNam: %d", n1.ngay, n1.thang, n1.nam);
    //dong file
    fclose(fp); 
}
Ngay: 11 Thang: 9 Nam: 2021

Giải thích qua về hai hàm fwrite()fread():

fwrite(&n1, sizeof(struct ngaysinh), 1, fp);

fread(&n1, sizeof(struct ngaysinh), 1, fp);

Hai hàm trên có 4 tham số truyền vào:

  • Tham số đầu tiên là địa chỉ của biến cần đọc (hoặc ghi)
  • Tham số thứ 2 là kích thước của biến cần đọc (hoặc ghi)
  • Tham số thứ 3 là số lượng kiểu dữ liệu
  • Tham số cuối cùng là con trỏ đã được trỏ tới file cần thao tác (ở đây là ngaysinh.bin)

Chú ý: Chương trình trên chỉ là một ví dụ minh họa cho việc mở và đọc ghi file nhị phân với các hàm fwrite()fread(). Hai hàm này đã được nêu ra ở bài trước (bạn đọc quên có thể đọc lại). Chi tiết về cách sử dụng fwrite()fread() sẽ được thể hiện ở những bài tiếp theo!