SỬ DỤNG HÀM TRONG C
CHƯƠNG 8 QUẢN LÝ TẬP TIN
8.4 TẬP TIN NHỊ PHÂN
8.4.1 Mở, đóng một tập tin nhị phân
Một tập tin nhị phân cũng được mở bằng hàm fopen(). Tuy nhiên, việc mở tập tin nhị phân hay tập tin văn bản sẽ được phân biệt nhau ở chế độ mở file.Bảng 8. 3 liệt kê các chế độ để mở một tập tin nhị phân.
Chế độ Ý nghĩa
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ở một tập tin nhị phân để đọc/ghi a+b Nối vào một tập tin nhị phân để đọc/ghi
Bảng 8. 3: Các chế độ mở tập tin nhị phân.
Ví dụ, để mở một tập tin có tên output.data trên ổ đĩa C để ghi ta sử dụng các câu lệnh sau:
FILE *fp;
fp = fopen ("C:\\output.data", "wb");
Một tập tin nhị phân cũng được đóng bằng hàm fclose() giống như một tập tin văn bản, ví dụ để đóng tập tin data.txt vừa mở ở trên, ta sử dụng câu lệnh:
fclose(fp);
8.4.2 Ghi dữ liệu vào một tập tin nhị phân
Trong thực tế, tập tin nhị phân thường được sử dụng để lưu trữ các khối dữ
liệu. Mỗi khối
bao gồm các byte liên tục, biểu diễn một cấu trúc dữ liệu phức tạp, chẳng hạn
như, một tập tin
dữ liệu có thể bao gồm nhiều cấu trúc có cùng thành phần cấu tạo, hoặc nó có thể
chứa nhiều
mảng có cùng kiểu và kích thước. Với những ứng dụng như vậy thường đòi hỏi
đọc toàn bộ
khối dữ liệu từ tập tin dữ liệu hoặc ghi toàn bộ khối vào tập tin dữ liệu hơn là đọc
hay ghi các
thành phần độc lập (nghĩa là các thành viên của cấu trúc hay các phần tử của
mảng) trong mỗi
khối riêng biệt.
Hàm fwrite() được dùng để ghi dữ liệu vào tập tin dữ liệu trong những tình huống như vậy. Hàm này có thể dùng để ghi bất kỳ kiểu dữ liệu nào. Nguyên mẫu của fwrite() là:
size_t fwrite (const void *buffer, size_t size, size_t count, FILE
*fp);
Trong đó, kiểu dữ liệu size_t được thêm vào C chuẩn để tăng tính tương thích của chương trình với nhiều hệ thống. Nó được định nghĩa trước như là một kiểu số nguyên đủ lớn để lưu giữ kết quả của hàm sizeof(). Đối với hầu hết các hệ
thống, size_t có thể được dùng như một số nguyên dương; buffer là một con trỏ trỏ đến thông tin sẽ được ghi vào tập tin, size làtổng số byte được ghi; count là số phần tử cần ghi; fp là con trỏ kiểu FILE, trỏ đến tập tin nhị phân đã được mở bằng lệnh fopen()với chế độ để ghi (wb/w+b).
Hàm này trả về số lượng các phần tử đã ghi vào tập tin nếu thao tác ghi thành công. Nếu giá trị này nhỏ hơn count thì đã xảy ra lỗi.
160
Chương trình sau đây sẽ tạo một file nhị phân có tên output.data ở ổ đĩa C và sử dụng hàm fwrite() để ghi một mảng kiểu số nguyên vào file.
Ví dụ 8.8:
#includ e<stdio .h>
intmain ( void ) {
FILE *b_fi;
intAry[10] =
{1,2,3,4,5,6,7,8,9,10};
inti, numwritten;
/*Open file in binary mode*/
b_fi =
fopen("C:\\output.data",
"w+b"); if (b_fi == NULL){
printf("Can not open file to read!"); return 1;
}
numwritten = fwrite( Ary, sizeof(int), 10, b_fi); if (numwritten==0)
printf("Could not write any item\n");
elseprintf( "Wrote %d items\n", numwritten );
fclose (b_fi);
}
Sau khi ghi xong dữ liệu, dòng thông báo:
Wrote 10 items
sẽ được in ra màn hình, chứng tỏ quá trình ghi dữ liệu đã thành công.
Chương trình sau đây sẽ khai báo và nhập dữ liệu cho một biến cấu trúc sinh
viên từ bàn
phím, sau đó tạo/mở một tập tin có tên student.data ở ổ đĩa C và sử dụng hàm
fwrite() để ghi
dữ liệu ra file.
Ví dụ 8.9:
#includ e<stdio .h>
typedef struct {
intday, month, year;
}Date;
structStudent{
char StudentI D[5];
char Name[30]
;
Date DBirth;
char Address[50];
};
i n t m a i n ( ) {
struct Student st; FILE
*b_fi;
int numwritten;
printf("\nInput data please\n");
printf("\nStudent ID:
");
scanf("%s",st.StudentI D); fflush(stdin);
printf("\nName: ");
161
gets(st.Name);
printf("\nDate of birth: ");
scanf("%d%d%d",&st.DBirth.day,&st.DBirth.month,
&st.DBirth.year); fflush(stdin);
printf("\nA ddress:");
gets(st.Add ress);
/*write data into file*/
b_fi =
fopen("C:\\student.data","wb
"); if (b_fi == NULL){
printf("Can not open file to read!"); return 1;
}
numwritten =
fwrite(&st,sizeof(structStudent),1,b_fi); if (numwritten==0)
printf("Could not write any iem");
else
printf( "Wrote %d items\n", numwritten ); fclose(b_fi);
}
Kết quả thực hiện chương trình như sau:
Input data please Student ID: 101
Name: Le Ngoc Trinh Date of birth:
15 10 1993 Address: Thanh Hoa
Nếu việc tạo file và ghi dữ liệuvào file thành công thì dòng thông báo Wrote 1 items
sẽ được hiển thị ra màn hình.
8.4.3 Đọc dữ liệu từ tập tin nhị phân
Hàm fread() có thể được dùng để đọc bất kỳ kiểu dữ liệu nào. Nguyên mẫu
của hàm như
sau:
size_t fread (void *buffer, size_t size, size_t count, FILE *fp);
Trong đó buffer là một con trỏ trỏ đến vùng nhớ sẽ nhận dữ liệu từ tập tin, size làtổng số byte cần đọc; count là số phần tử cần đọc; fp là con trỏ kiểu FILE, trỏ đến tập tin nhị phân đã được mở bằng lệnh fopen()với chế độ để đọc (rb/r+b).
Hàm này trả về số lượng các phần tử đã đọc được (nếu thao tác đọc thành công). Nó trả về
0 nếu đọc đến cuối tập tin hoặc xảy ra lỗi.
Chương trình sau đây sẽ mở tập tin nhị phân output.data ở trên, với chế độ mở để đọc và sử dụng hàm fread() để đọc và hiển thị ra màn hình các dữ liệu đã được ghi trong file.
Ví dụ 8.10:
#includ e<stdio .h>
intmain ( void )
{ FILE *b_fo;
intA[10];
intnumread;
162
b_fo = fopen("C:\\output.data",
"r+b"); if (b_fo == NULL){
printf("Can not open file to read!"); return 1;
}
numread= fread( A, sizeof( int ), 10, b_fo); if (numread==0){
printf("Could not read any item\n");
} else{
printf( "Read %d items.\n", numread);
for (inti=0; i<10; i++){
printf("%d ", A[i]);
}
fclose(b_fo);} }
Kết quả thực hiện của chương trình như sau:
Read 10 items.
1 2 3 4 5 6 7 8 9 10
Chương trình sau đây sẽ sử dụng hàm fread()để đọc dữ liệu có kiểu cấu trúc Student từ file student.data đã được tạo ra ở trên.
Ví dụ 8.11:
#includ e<stdio .h>
intmain () {
struct Studen tst;
FILE
*b_fo;
intnumread;
b_fo =
fopen("C:\\student.data","rb
"); if (b_fo == NULL){
printf("Can not open file to read!"); return 1;
}
numread =
fread(&st,sizeof(structStudent),1,b_fo);
if (numread==0)
printf("Could not read any iem");
else{
printf( "Read %d items\n", numread );
printf("Readinformation:\n"
); printf("%s\n",st.StudentID)
; printf("%s\n",st.Name);
printf("%d/%d/
%d\n",st.DBirth.day,st.DBirth.month, st.DBirth.year);
printf("%s\n", st.Address);
}
fclose(b_fo);
}
Nếu đọc dữ liệu thành công (tập tin student.data đã được tạo và dữ liệu được lưu vào file theo đúng định dạng), kết quả thực hiện của chương trình như sau:
Read 1 items
163
Read informa tion:
101 Le Ngo c Tri nh 15/
10/
199 3 Tha nh Hoa