Xử lý tệp C

Trong hướng dẫn này, bạn sẽ tìm hiểu về cách xử lý tệp trong C. Bạn sẽ học cách xử lý I/O tiêu chuẩn trong C bằng cách sử dụng fprintf(), fscanf(), fread(), fwrite(), fseek(), v.v. với sự trợ giúp của các ví dụ.

Tệp là một vùng chứa trong các thiết bị lưu trữ máy tính được sử dụng để lưu trữ dữ liệu.

Tại sao cần có tệp?

  • When a program is terminated, the entire data is lost. Storing in a file will preserve your data even if the program terminates.
  • If you have to enter a large number of data, it will take a lot of time to enter them all.
    However, if you have a file containing all the data, you can easily access the contents of the file using a few commands in C.
  • You can easily move your data from one computer to another without any changes.

Các loại tệp

Khi xử lý tệp, có hai loại tệp bạn nên biết:

  1. Tệp văn bản
  2. Tệp nhị phân

1. Tệp văn bản

Tệp văn bản là tiep.txt bình thường . Bạn có thể dễ dàng tạo các tệp văn bản bằng bất kỳ trình soạn thảo văn bản đơn giản nào như Notepad.

Khi bạn mở các tệp đó, bạn sẽ thấy tất cả nội dung trong tệp dưới dạng văn bản thuần túy. Bạn có thể dễ dàng chỉnh sửa hoặc xóa nội dung.

Chúng cần nỗ lực tối thiểu để duy trì, dễ đọc và cung cấp ít bảo mật nhất và chiếm không gian lưu trữ lớn hơn.

2. Tệp nhị phân

Các tệp nhị phân chủ yếu là tiep.bin trong máy tính của bạn.

Thay vì lưu trữ dữ liệu dưới dạng văn bản thuần túy, họ lưu trữ nó ở dạng nhị phân (0 và 1).

Chúng có thể chứa một lượng dữ liệu cao hơn, không thể đọc được dễ dàng và cung cấp khả năng bảo mật tốt hơn các tệp văn bản.

Thao tác tệp

Trong C, bạn có thể thực hiện bốn thao tác chính trên tệp, văn bản hoặc nhị phân:

  1. Tạo một tệp mới
  2. Mở một tệp hiện có
  3. Đóng tệp
  4. Đọc và ghi thông tin vào một tệp

Làm việc với tệp

Khi làm việc với tệp, bạn cần khai báo một con trỏ kiểu tệp. Khai báo này là cần thiết để giao tiếp giữa tệp và chương trình.

FILE *fptr;

Mở tệp – để tạo và chỉnh sửa

Mở tệp được thực hiện bằng cách sử dụng fopen()chức năng được xác định trong stdio.htệp tiêu đề.

Cú pháp để mở tệp trong I / O tiêu chuẩn là:

ptr = fopen("fileopen","mode");

Ví dụ,

fopen("E:\\cprogram\\newprogram.txt","w");

fopen("E:\\cprogram\\oldprogram.bin","rb");
  • Let’s suppose the file newprogram.txt doesn’t exist in the location E:\cprogram. The first function creates a new file named newprogram.txt and opens it for writing as per the mode ‘w’.
    The writing mode allows you to create and edit (overwrite) the contents of the file.
  • Now let’s suppose the second binary file oldprogram.bin exists in the location E:\cprogram. The second function opens the existing file for reading in binary mode ‘rb’.
    The reading mode only allows you to read the file, you cannot write into the file.
ModeMeaning of ModeDuring Inexistence of file
rOpen for reading.If the file does not exist, fopen() returns NULL.
rbOpen for reading in binary mode.If the file does not exist, fopen() returns NULL.
wOpen for writing.If the file exists, its contents are overwritten.
If the file does not exist, it will be created.
wbOpen for writing in binary mode.If the file exists, its contents are overwritten.
If the file does not exist, it will be created.
aOpen for append.
Data is added to the end of the file.
If the file does not exist, it will be created.
abOpen for append in binary mode.
Data is added to the end of the file.
If the file does not exist, it will be created.
r+Open for both reading and writing.If the file does not exist, fopen() returns NULL.
rb+Open for both reading and writing in binary mode.If the file does not exist, fopen() returns NULL.
w+Open for both reading and writing.If the file exists, its contents are overwritten.
If the file does not exist, it will be created.
wb+Open for both reading and writing in binary mode.If the file exists, its contents are overwritten.
If the file does not exist, it will be created.
a+Open for both reading and appending.If the file does not exist, it will be created.
ab+Open for both reading and appending in binary mode.If the file does not exist, it will be created.

Đóng tệp

Tệp (cả văn bản và nhị phân) phải được đóng sau khi đọc / ghi.

Đóng một tệp được thực hiện bằng cách sử dụng fclose()hàm.

fclose(fptr);

Đây, fptrlà một con trỏ tệp được liên kết với tệp sẽ được đóng.

Đọc và ghi vào tệp văn bản

Để đọc và ghi vào tệp văn bản, chúng tôi sử dụng các hàm fprintf()fscanf().

Chúng chỉ là các phiên bản tệp của printf()và scanf(). Sự khác biệt duy nhất là fprint()và fscanf()mong đợi một con trỏ đến cấu trúc FILE.


Ví dụ 1: Ghi vào tệp văn bản

#include <stdio.h>
#include <stdlib.h>

int main()
{
   int num;
   FILE *fptr;

   // use appropriate location if you are using MacOS or Linux
   fptr = fopen("C:\\program.txt","w");

   if(fptr == NULL)
   {
      printf("Error!");   
      exit(1);             
   }

   printf("Enter num: ");
   scanf("%d",&num);

   fprintf(fptr,"%d",num);
   fclose(fptr);

   return 0;
}

Chương trình này lấy một số từ người dùng và lưu trữ trong tệp program.txt.

Sau khi biên dịch và chạy chương trình này, bạn có thể thấy một tệp văn bản program.txtđược tạo trong ổ C của máy tính. Khi bạn mở tệp, bạn có thể thấy số nguyên bạn đã nhập.


Ví dụ 2: Đọc từ tệp văn bản

#include <stdio.h>
#include <stdlib.h>

int main()
{
   int num;
   FILE *fptr;

   if ((fptr = fopen("C:\\program.txt","r")) == NULL){
       printf("Error! opening file");

       // Program exits if the file pointer returns NULL.
       exit(1);
   }

   fscanf(fptr,"%d", &num);

   printf("Value of n=%d", num);
   fclose(fptr); 
  
   return 0;
}

Chương trình này đọc số nguyên có trong program.txttệp và in ra màn hình.

Nếu bạn đã tạo thành công tệp từ Ví dụ 1 , chạy chương trình này sẽ nhận được số nguyên bạn đã nhập.

Các chức năng khác như fgetchar()fputc()v.v. có thể được sử dụng theo cách tương tự.

Đọc và ghi vào tệp nhị phân

Các chức năng fread()và fwrite()được sử dụng để đọc và ghi vào tệp trên đĩa tương ứng trong trường hợp tệp nhị phân.


Ghi vào tệp nhị phân

Để ghi vào tệp nhị phân, bạn cần sử dụng fwrite()hàm. Các hàm có bốn đối số:

  1. địa chỉ của dữ liệu được ghi vào đĩa
  2. kích thước của dữ liệu được ghi vào đĩa
  3. số loại dữ liệu như vậy
  4. con trỏ đến tệp mà bạn muốn ghi.
fwrite(addressData, sizeData, numbersData, pointerToFile);

Ví dụ 3: Ghi vào tệp nhị phân bằng fwrite ()

#include <stdio.h>
#include <stdlib.h>

struct threeNum
{
   int n1, n2, n3;
};

int main()
{
   int n;
   struct threeNum num;
   FILE *fptr;

   if ((fptr = fopen("C:\\program.bin","wb")) == NULL){
       printf("Error! opening file");

       // Program exits if the file pointer returns NULL.
       exit(1);
   }

   for(n = 1; n < 5; ++n)
   {
      num.n1 = n;
      num.n2 = 5*n;
      num.n3 = 5*n + 1;
      fwrite(&num, sizeof(struct threeNum), 1, fptr); 
   }
   fclose(fptr); 
  
   return 0;
}

Trong chương trình này, chúng tôi tạo một tệp mới program.bintrong ổ C.

Chúng ta khai báo một cấu trúc threeNumvới ba số – n1, n2 và n3 , và định nghĩa nó trong hàm main là num.

Bây giờ, bên trong vòng lặp for, chúng tôi lưu trữ giá trị vào tệp bằng cách sử dụng fwrite().

Tham số đầu tiên lấy địa chỉ là num và tham số thứ hai lấy kích thước của cấu trúc threeNum.

Vì chúng tôi chỉ chèn một trường hợp của num , nên tham số thứ ba là 1. Và, tham số cuối cùng *fptrtrỏ đến tệp chúng tôi đang lưu trữ dữ liệu.

Cuối cùng, chúng tôi đóng tệp.

Đọc từ một tệp nhị phân

Hàm fread()cũng nhận 4 đối số tương tự như fwrite()hàm như trên.

fread(addressData, sizeData, numbersData, pointerToFile);

Ví dụ 4: Đọc từ tệp nhị phân bằng fread()

#include <stdio.h>
#include <stdlib.h>

struct threeNum
{
   int n1, n2, n3;
};

int main()
{
   int n;
   struct threeNum num;
   FILE *fptr;

   if ((fptr = fopen("C:\\program.bin","rb")) == NULL){
       printf("Error! opening file");

       // Program exits if the file pointer returns NULL.
       exit(1);
   }

   for(n = 1; n < 5; ++n)
   {
      fread(&num, sizeof(struct threeNum), 1, fptr); 
      printf("n1: %d\tn2: %d\tn3: %d", num.n1, num.n2, num.n3);
   }
   fclose(fptr); 
  
   return 0;
}

Trong chương trình này, bạn đọc cùng một tệp program.binvà lặp lại từng bản ghi một.

Nói một cách dễ hiểu, bạn đọc một threeNumbản ghi có threeNumkích thước từ tệp được trỏ bởi * fptr vào cấu trúc num .

Bạn sẽ nhận được các bản ghi giống như bạn đã chèn trong Ví dụ 3 .


Lấy dữ liệu bằng fseek()

Nếu bạn có nhiều bản ghi bên trong một tệp và cần truy cập một bản ghi ở một vị trí cụ thể, bạn cần phải lặp qua tất cả các bản ghi trước nó để lấy bản ghi.

Điều này sẽ lãng phí rất nhiều bộ nhớ và thời gian hoạt động. Có thể đạt được một cách dễ dàng hơn để truy cập dữ liệu cần thiết bằng cách sử dụng fseek().

Như tên cho thấy, fseek()tìm kiếm con trỏ đến bản ghi đã cho trong tệp.

Cú pháp của fseek()

fseek(FILE * stream, long int offset, int whence);

Luồng tham số đầu tiên là con trỏ đến tệp. Tham số thứ hai là vị trí của bản ghi được tìm thấy và tham số thứ ba chỉ định vị trí bắt đầu offset.

WhenceMeaning
SEEK_SETStarts the offset from the beginning of the file.
SEEK_ENDStarts the offset from the end of the file.
SEEK_CURStarts the offset from the current location of the cursor in the file.

Ví dụ 5: fseek ()

#include <stdio.h>
#include <stdlib.h>

struct threeNum
{
   int n1, n2, n3;
};

int main()
{
   int n;
   struct threeNum num;
   FILE *fptr;

   if ((fptr = fopen("C:\\program.bin","rb")) == NULL){
       printf("Error! opening file");

       // Program exits if the file pointer returns NULL.
       exit(1);
   }
   
   // Moves the cursor to the end of the file
   fseek(fptr, -sizeof(struct threeNum), SEEK_END);

   for(n = 1; n < 5; ++n)
   {
      fread(&num, sizeof(struct threeNum), 1, fptr); 
      printf("n1: %d\tn2: %d\tn3: %d\n", num.n1, num.n2, num.n3);
      fseek(fptr, -2*sizeof(struct threeNum), SEEK_CUR);
   }
   fclose(fptr); 
  
   return 0;
}

Chương trình này sẽ bắt đầu đọc các bản ghi từ tệp program.bintheo thứ tự ngược lại (từ cuối đến trước) và in ra.









Gõ tìm kiếm nhanh...