0965303260
TP. Hồ Chí Minh

[C]. Đọc Ghi File Text

Đọc ghi file trong ngôn ngữ lập trình C tương tự như việc bạn nhập xuất từ bàn phím, bài học này sẽ giúp các bạn làm việc với tập tin một cách tự tin hơn

NỘI DUNG : 

  • Hàm fopen()
  • Ghi nội dung vào file
  • Đọc nội dung từ file

image

1. Tạo file

Để làm việc với file thì đầu tiên bạn cần mở file đó lên, trong C để chương trình có thể làm việc với file bạn cần thông qua 1 con trỏ kiểu FILE

Có 2 kiểu file là file text (bạn có thể đọc được nội dung) và file nhị phân, trong bài học này mình sẽ hướng dẫn cách dùng file text trước.

Cú pháp khai báo con trỏ FILE : 

FILE *f;

Sau khi khai báo con trỏ file thì bạn có thể dùng nó để mở file với hàm fopen(), hàm này nằm trong thư viện

Cú pháp : 

FILE *f;
f = fopen ("ten_file", "mode");

Tham số thứ nhất trong fopen() là tên file mà bạn muốn mở, nếu bạn sử dụng file nằm trong cùng thư mục với file mã nguồn thì bạn chỉ cần tên file

Ví dụ : 

#include "stdio.h"

int main(){
    FILE *f;
    f = fopen("input.txt", "r");
}

Nếu bạn muốn sử dụng file nằm đâu đó ở các thư mục khác với file mã nguồn thì bạn cần truyền vào tên file là đường dẫn duyệt đối.

Ví dụ : 

#include "stdio.h"

int main(){
    FILE *f;
    f = fopen("C:/CNTT/28Tech/input.txt", "r");
}

Tham số thứ 2 trong hàm fopen() chính là mode mở file, nó sẽ chỉ định việc bạn mở file lên để đọc, ghi file và đang đọc ghi với file text hay file nhị phân

Các mode mở file chính : 

ModeÝ nghĩaChú ý
rMở file để đọcNếu file không tồn tại thì hàm fopen() trả về con trỏ NULL
rbMở file để đọc theo kiểu file nhị phânNếu file không tồn tại thì hàm fopen() trả về con trỏ NULL
wMở file để ghiNếu file đã tồn tại thì sẽ làm việc với file đó, nếu file chưa tồn tại sẽ tạo 1 file mới
wbMở file để ghi theo kiểu file nhị phânNếu file đã tồn tại thì sẽ làm việc với file đó, nếu file chưa tồn tại sẽ tạo 1 file mới
aMở file text lên để ghi tiếp vào cuối file mà không xóa nội dung cũ trong fileNếu file đã tồn tại thì sẽ làm việc với file đó, nếu file chưa tồn tại sẽ tạo 1 file mới
abMở file nhị phân lên để ghi tiếp vào cuối file mà không xóa nội dung cũ trong fileNếu file đã tồn tại thì sẽ làm việc với file đó, nếu file chưa tồn tại sẽ tạo 1 file mới
r+Mở file để vừa đọc vừa ghiNếu file không tồn tại thì hàm fopen() trả về con trỏ NULL
rb+Mở file để vừa đọc vừa ghi theo kiểu nhị phânNếu file không tồn tại thì hàm fopen() trả về con trỏ NULL
w+Mở file để vừa đọc vừa ghiNếu file đã tồn tại thì sẽ làm việc với file đó, nếu file chưa tồn tại sẽ tạo 1 file mới
wb+Mở file để vừa đọc vừa ghi theo kiểu nhị phânNếu file đã tồn tại thì sẽ làm việc với file đó, nếu file chưa tồn tại sẽ tạo 1 file mới
a+Mở file lên vừa để đọc và ghi vào cuối fileNếu file đã tồn tại thì sẽ làm việc với file đó, nếu file chưa tồn tại sẽ tạo 1 file mới
ab+Mở file để vừa đọc vừa ghi vào cuối file theo kiểu nhị phânNếu file đã tồn tại thì sẽ làm việc với file đó, nếu file chưa tồn tại sẽ tạo 1 file mới


Sau khi đọc ghi xong file bạn nên đóng file lại bằng hàm fclose()

Cú pháp : 

FILE *f;
fclose( f );


2. Ghi nội dung vào file 

Để ghi nội dung vào file bạn làm tương tự như bạn in nội dung ra màn hình, các hàm ghi nội dung vào file thường có thêm chữ f ở trước.

Để ghi nội dung vào file thì bạn chỉ cần dùng hàm fprintf() là đủ.

Hàm fprintf() : 

Hàm fprintf() được dùng để ghi nội dung vào file tương tự như hàm printf

Cú pháp : 

int fprintf ( FILE * f, const char * format, ... );

Ví dụ 1 : Ghi 1 số nguyên, 1 số thực, 1 kí tự và 1 chuỗi ký tự vào trong file output.txt

#include "stdio.h"

int main(){
    FILE *f;
    f = fopen("output.txt", "w");
    char s[100] = "28tech.com.vn";
    printf("%d %.2lf %.c %s\n", 100, 3.14, '@', s);
    fclose(f);
    return 0;
}

File output.txt

100 3.14 @ 28tech.com.vn

Ví dụ 2 : Ghi vào file prime.txt các số nguyên tố từ 1 tới 200, mỗi dòng tối đa 10 số

#include "stdio.h"
#include "math.h"

int prime(int n){
    if(n < 2) return 0;
    for(int i = 2; i <= sqrt(n); i++){
        if(n % i == 0){
            return 0;
        }
    }
    return 1;
}

int main(){
    FILE *f;
    f = fopen("prime.txt", "w");
    int dem = 0;
    for(int i = 1; i <= 200; i++){
        if(prime(i)){
            fprintf(f, "%d ", i);
            ++dem;
            if(dem % 10 == 0){
                //ghi dấu xuống dòng
                fprintf(f, "\n");
            }
        }
    }
    fclose(f);
    return 0;
}

File prime.txt

2 3 5 7 11 13 17 19 23 29 
31 37 41 43 47 53 59 61 67 71 
73 79 83 89 97 101 103 107 109 113 
127 131 137 139 149 151 157 163 167 173 
179 181 191 193 197 199 

Ví dụ 3 : Mở file output.txt và ghi tiếp vào cuối file 

Để nội dung cũ trong file không bị xóa hết trước khi đọc thì bạn cần dùng mode mở là "a". 

Bạn có thể chạy mã nguồn này nhiều lần và sẽ thấy nội dung cũ được giữ nguyên và việc ghi nội dung được thực hiện tiếp tục từ cuối file

#include "stdio.h"
#include "math.h"

int main(){
    FILE *f;
    f = fopen("output.txt", "a");
    fprintf(f, "28tech\n");
    fclose(f);
    return 0;
}

File output.txt sau 4 lần chạy mã nguồn

28tech
28tech
28tech
28tech


3. Đọc nội dung từ file

Để đọc nội dung từ file bạn sử dụng 2 hàm chính là fscanf() và fgets(), ngoài ra còn có fgetchar()

Hàm fscanf()

Hàm này tương tự hàm scanf() mà bạn hay dùng khi đọc từ bàn phím, bây giờ bạn đọc từ file.

Cú pháp : 

int fscanf ( FILE * f, const char * format, ... );

Để đọc được file thì bạn cần biết file được lưu trữ như thế nào

Ví dụ 1 : Đọc số nguyên int, số thực double, chuỗi ký tự không có dấu cách trong file input.txt, sau đó in ra màn hình

#include "stdio.h"
#include "math.h"

int main(){
    FILE *f;
    f = fopen("input.txt", "r");
    if(f == NULL){
        printf("Cannot open file !\n");
    }
    else{
        int n;
        double d;
        char s[1000];
        fscanf(f, "%d %lf %s", &n, &d, s);
        printf("Data : %d %.2lf %s\n", n, d, s);
        fclose(f);
    }
    return 0;
}

File input.txt

28 3.14 28tech.com.vn

Output : 

Data : 28 3.14 28tech.com.vn

Ví dụ 2 : Đọc mảng số nguyên từ file input.txt và ghi vào file output.txt các số nguyên tố trong dãy

File input.txt có khuôn mẫu : Dòng đầu tiên là số lượng phần tử trong mảng, dòng thứ 2 là các số trong mảng

10
2 7 8 10 2 5 100 80 29 32

Code : 

#include "stdio.h"
#include "math.h"

int prime(int n){
    if(n < 2) return 0;
    for(int i = 2; i <= sqrt(n); i++){
        if(n % i == 0) return 0;
    }
    return 1;
}

int main(){
    FILE *f1, *f2;
    f1 = fopen("input.txt", "r");
    if(f1 == NULL){
        printf("Cannot open file !\n");
    }
    else{
        f2 = fopen("output.txt", "w");
        int n, x;
        fscanf(f1, "%d", &n);
        for(int i = 0; i < n; i++){
            fscanf(f1, "%d", &x);
            if(prime(x)){
                fprintf(f2, "%d ", x);
            }
        }
        fclose(f1); fclose(f2);
    }
    return 0;
}

File output.txt

2 7 2 5 29 


Hàm fgets()

Hàm fgets() được sử dụng tương tự hàm gets(), dùng để đọc chuỗi ký tự có dấu cách. 

Hàm này cũng bị trôi lệnh như hàm gets nên bạn cần lưu ý xử lý, ngoài ra nó còn đọc cả ký tự enter ở cuối dòng nên bạn cần loại bỏ ký tự enter này khỏi chuỗi

Cú pháp : 

char * fgets ( char * str, int num, FILE * f);

Tham số : 

  • char* str : Xâu bạn muốn lưu nội dung đọc được
  • num : Số lượng kí tự tối đa bạn muốn đọc
  • f : Con trỏ file 

Ví dụ 1: 

#include "stdio.h"
#include "math.h"
#include "string.h"

int main(){
    FILE *f;
    f = fopen("input.txt", "r");
    if(f == NULL){
        printf("Cannot open file !\n");
    }
    else{
        char s[1000];
        fgets(s, 1000, f);
        //Xoa enter
        s[strlen(s) - 1] = '\0';
        printf("Data : %s", s);
        fclose(f);
    }
    return 0;
}

File input.txt 

28tech blog

Output : 

Data : 28tech blog


Ví dụ 2 : Xử lý trôi lệnh khi dùng fgets()

Nếu trước fgets() bạn dùng fscanf() và để dư kí tự enter sẽ bị trôi lệnh, cách xử lý là loại bỏ enter bằng hàm fgetc(), hàm này sẽ đọc 1 kí tự trong file

#include "stdio.h"
#include "math.h"
#include "string.h"

int main(){
    FILE *f;
    f = fopen("input.txt", "r");
    if(f == NULL){
        printf("Cannot open file !\n");
    }
    else{
        int n;
        fscanf(f, "%d", &n);
        //xử lý kí tự enter
        fgetc(f);
        char s[1000];
        fgets(s, 1000, f);
        //Xoa enter
        s[strlen(s) - 1] = '\0';
        printf("Data : %d\n%s", n, s);
        fclose(f);
    }
    return 0;
}

File input.txt :

28
28tech blog

Output : 

Data : 28
28tech blog

Bạn cũng có thể thay fgetc() bằng  fscanf(f, "\n");



Như vậy mình đã hướng dẫn xong cách đọc ghi file text trong C, bạn chỉ cần nắm chắc các hàm là fprintf(), fscanf(), fgets() và fgetc() là có thể làm việc với file một cách thuần thục. 

Việc đọc ghi file giống với đọc ghi từ bàn phím và màn hình, có điều luồng vào và luồng ra khác nhau.