File I/O

Open File

Chúng ta sử dụng hàm fopen để mở file hoặc tạo file mới. Hàm này có dạng như sau:

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

Trong đó filename là đường dẫn tương đối hoặc tuyệt đối đến file. Còn mode được mô tả như sau:

Mode Mô tả
r Mở file để đọc. Nếu không tìm thấy file, hàm này sẽ về con trỏ NULL.
w Mở file để ghi. Nếu file không tồn tại, hàm này sẽ tạo file mới. Hàm này sẽ luôn ghi từ đầu file.
a Mở file để ghi vào cuối file. Nếu không tồn tại, hàm này sẽ tạo file mới.
r+ Mở file để đọc và ghi
w+ Mở file để đọc và ghi. Nếu file không tồn tại, mode này sẽ tạo file mới. Mode này sẽ xóa hết nội dung cũ trước khi ghi.
a+ Mở file để đọc và ghi. Nếu file không tồn tại, mode này sẽ tạo file mới. Việc đọc sẽ từ đầu file, tuy nhiên ghi thì ở cuối file.

Nếu cần đọc ghi nhị phân với file thì có các mode tương ứng
“rb”, “wb”, “ab”, “rb+”, “r+b”, “wb+”, “w+b”, “ab+”, “a+b”

Hàm fopen sẽ trả về NULL nếu không thể mở file, nếu thành công sẽ trả về con trỏ file.

Đóng file

Để đóng file, chúng sử dụng hàm fclose. Hàm này sẽ đẩy các dữ liệu từ buffer vào file (nếu ghi file), đóng file và giải phóng các bộ nhớ lúc mở file. Hàm sẽ trả về 0 nếu thành công hoặc EOF nếu có lỗi. Hàm này có dạng như sau.

1
int fclose(FILE *fp);

Ghi nội dung vào file

Có ba hàm thường dùng để ghi nội dung vào file gồm fputc, fputsfprintf. Mô tả từng hàm như sau.

Hàm Prototype Mô tả
fputc int fputc(int c, FILE *fp); Ghi một ký tự vào file
fputs int fputs(const char *s, FILE *fp); Ghi một string vào file
fprintf int fprintf(FILE *fp, const char * format, params…) Ghi một string được định dạng vào file

Ví dụ sử dụng các hàm này như sau

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
FILE *fp; // con trỏ tới file
fp = fopen("./test.txt", "w+"); // mở file, chế độ đọc ghi đè
if (fp == NULL) {
  perror("Error opening file");
  return 1;
}
fprintf(fp, "fprintf %d...\n", 100); // ghi nội dung format vào file fp
fputs("This is testing for fputs...\n", fp); // ghi một string vào file
fputc('a', fp); // ghi một ký tự vào file
fclose(fp); // đóng file

Có thể sử dụng hàm ferror để kiểm tra lỗi khi ghi vào file.
Chương trình sau sẽ ghi vào một file mà file này được mở chỉ để đọc.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
FILE * pFile;
pFile = fopen("./myfile.txt","r"); // mở file chế độ chỉ đọc
if (pFile == NULL) {
  perror("Error opening file");
} else {
  fputc('x',pFile); // cố tình ghi lỗi vì file chỉ đọc
  if (ferror(pFile)) { // kiểm tra xem lỗi khi ghi vào file không
    fprintf(stderr, "Error Writing to myfile.txt\n"); // hiển thị lỗi
  }
  fclose (pFile);
}

Đọc nội dung từ file

Tương ứng với các hàm ghi nội dung file, một số hàm sẽ đọc nội dung từ file bao gồm fgetc, fgets, fscanf. Mô tả từng hàm như sau.

Mô tả các hàm như sau:

Hàm Prototype Mô tả
fgetc int fgetc(FILE * fp ); đọc một ký tự
fgets char *fgets(char *buffer, int n, FILE *fp ); đọc một string
fscanf int fscanf(FILE *fp, const char *format, …) đọc một string đã format

Hàm fgets đọc tới n - 1 ký tự từ file vào buffer, ký tự tiếp theo là kết thúc string \0. Ví dụ về đọc file như sau:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
FILE *fp;
char buff[255];

fp = fopen("./myfile.txt", "w+"); // mở file ghi
if (fp != NULL) {
  fputs("This is testing for fputs...\n", fp);
  fputs("Hello to ninja website...\n", fp);
  fclose(fp);
}

fp = fopen("./myfile.txt", "r"); // mở lại file để đọc
if (fp != NULL) {
  // đọc string tới ký tự khoảng trắng hoặc xuống dòng
  fscanf(fp, "%s", buff); 
  printf("1: %s\n", buff ); // "1: This"

  fgets(buff, 10, fp); // đọc 9 ký tự, thêm '\0' là 10 ký tự
  printf("2: %s\n", buff ); // "2:  is testi"
  
  char c = fgetc(fp); // đọc 1 ký tự
  printf("3: %c\n", c ); // "3: n"
  fclose(fp);
}