Giáo trình Lập trình cơ bản C - Bài 22: Quản lý tập tin (Tiếp theo)

Bài 22  
Quản Tập Tin  
Mục tiêu:  
Kết thúc bài học này, bạn thể:  
Thực hiện các thao tác trên tập tin văn bản tập tin nhị phân  
Mở đóng tập tin  
Đọc từ tập tin và ghi vào tập tin  
Sử dụng con trỏ tập tin.  
Các bước được cho trong bài này được giải thích cặn kẽ, dễ hiểu duy cẩn thận từ đầu đến cuối.  
Bài đã được viết để đáp ứng được mục tiêu học để thể hiểu hoàn toàn về công cụ. Xin hãy thực  
hiện theo các bước một cách cẩn thận.  
Phần I – Trong thời gian 1 giờ 30 phút đầu:  
22.1  
Quản tập tin trong C  
C cung cấp một giao diện đồng nhất cho việc quản nhập xuất. Các phương pháp truy cập  
tập tin cũng giống như các phương pháp quản lý các thiết bị khác. Giải pháp cho tính đồng  
nhất này là trong C không có kiểu tập tin. C xem tất cả các tập tin là stream.  
22.1.1 Đọc, ghi và truy cập dữ liệu trong tập tin  
một số hàm xử tập tin trong tập tin header stdio.h. Chúng ta hãy viết một chương trình C  
sử dụng những hàm này. Chương trình tạo một hệ thống ngân hàng đơn giản. Các chi tiết  
khách hàng được nhập vào và lưu trong một tập tin gọi customer. Chi tiết của các giao dịch  
như gửi tiền và rút tiền được kiểm tra hợp lệ trên tập tin customer. Các giao dịch hợp lệ được  
ghi nhận trong tập tin trans. Một báo cáo về các khách hàng có số vốn thấp được in ra. Các  
bước được liệt như sau:  
1. Định nghĩa một structure để lưu trữ dữ liệu về khách hàng và giao dịch. Câu lệnh sẽ là:  
struct cust_st  
{
int acc_no;  
char cust_nm[30];  
float bal;  
};  
struct tran_st  
{
int acc_no;  
char trantype;  
float amt;  
};  
2. Hiển thị một danh mục để thực hiện các thao tác khác nhau dựa trên lựa chọn của người  
dùng. Câu lệnh sẽ là:  
while(choice != 4)  
{
clrscr();  
printf("\nSelect choice from menu\n\n1. Accept  
customer details\n2. Record Withdrawal/Deposit  
Quản tập tin  
305  
transaction\n3. Print Low Balance Report\n4.  
Exit\n\nEnter choice: ");  
scanf(" %d", &choice);  
.
.
}
3. Gọi các hàm tương ứng dựa vào lựa chọn của người dùng. Câu lệnh sẽ là:  
if(choice == 1)  
addcust();  
else if(choice == 2)  
rectran();  
else if(choice == 3)  
prnlowbal();  
4. Trong hàm thêm chi tiết của khách hàng, định nghĩa một con trỏ tập tin để kết hợp với tập  
tin customer. Khai báo một biến cấu trúc để nhập dữ liệu của khách hàng. Câu lệnh sẽ là:  
FILE *fp;  
struct cust_st custdata;  
5. Mở tập tin customer theo chế độ append để thể thêm các mẫu tin mới. Xác nhận rằng  
thao tác mở tập tin đã được thực hiện. Câu lệnh sẽ là:  
if((fp = fopen("customer", "a+")) == NULL)  
{
printf("\nERROR opening customer file");  
getch();  
return;  
}
6. Nhập dữ liệu khách hàng vào biến cấu trúc và ghi dữ liệu vào tập tin customer. Câu lệnh sẽ  
là:  
fwrite(&custdata, sizeof(struct cust_st), 1, fp);  
7. Đóng tập tin customer sau khi nhập dữ liệu. Câu lệnh sẽ là:  
fclose(fp);  
8. Trong hàm dùng để ghi các giao dịch, định nghĩa biến con trỏ để trỏ đến tập tin customer  
tập tin trans. Và định nghĩa biến cấu trúc để nhập vào dữ liệu của giao dịch đọc dữ  
liệu khách hàng. Câu lệnh sẽ là:  
FILE *fp1, *fp2;  
struct cust_st custdata;  
struct tran_st trandata;  
9. Mở hai tập tin theo chế độ thích hợp. Tập tin customer phải mở để đọc cập nhật, trong  
khi tập tin trans phải cho phép thêm các mẫu tin mới. Câu lệnh sẽ là:  
if((fp1=fopen("customer", "r+w"))==NULL)  
{
printf("\nERROR opening customer file");  
getch();  
return;  
}
306  
Lập trình cơ bản C  
if((fp2 = fopen("trans", "a+")) == NULL)  
{
printf("\nERROR opening transaction file");  
getch();  
return;  
}
10.Nhập vào số tài khoản cho giao dịch bảo đảm rằng tồn tại trong tập tin customer. Câu  
lệnh sẽ là:  
while((fread(&custdata, size, 1, fp1)) == 1 && found == 'n')  
{
if(custdata.acc_no == trandata.acc_no)  
{
found='y';  
break;  
}
}
11.Để bảo đảm nhập vào một kiểu giao dịch hợp lệ, câu lệnh sẽ là:  
if(trandata.trantype!='D' && trandata.trantype!='d'  
&& trandata.trantype!='W' && trandata.trantype!='w')  
printf("\t\tInvalid transaction type, please reenter");  
12.Đối với các giao dịch rút tiền, phải bảo đảm rằng số tiền rút ra phải sẳn có trong tài khoản  
của khách hàng. Nếu sẳn có, cập nhật số tiền còn lại trong tài khoản. Cũng cần cập nhật số  
tiền trong tài khoản cho các giao dịch gửi tiền. Câu lệnh sẽ là:  
if(trandata.trantype=='W' || trandata.trantype=='w')  
{
if(trandata.amt>custdata.bal)  
printf("\nAccount balance is %.2f. Please  
reenter withdrawal amount.", custdata.bal);  
else  
{
custdata.bal-=trandata.amt;  
.
.
}
}
else  
{
custdata.bal+=trandata.amt;  
.
.
}
13.Ghi mẫu tin chứa giao dịch mới vào tập tin trans và cập nhật mẫu tin của khách hàng trong  
tập tin customer. Câu lệnh sẽ là:  
fwrite(&trandata, sizeof(struct tran_st), 1, fp2);  
fseek(fp1, (long)(-size), 1);  
fwrite(&custdata, size, 1, fp1);  
Quản tập tin  
307  
Lưu ý rằng trong suốt quá trình kiểm tra số tài khoản của khách hàng, mẫu tin đọc cuối  
cùng là của khách hàng đang thực hiện giao dịch. vậy, con trỏ tập tin của tập tin  
customer phải nằm ở cuối của mẫu tin cần cập nhật. Con trỏ tập tin sẽ được đặt lại vị trí  
về đầu của mẫu tin sử dụng hàm fseek(). Ở đây size một biến số nguyên chứa kích cở  
của cấu trúc cho dữ liệu khách hàng.  
14.Đóng hai tập tin sau khi đã nhập giao dịch. Câu lệnh sẽ là:  
fclose(fp1);  
fclose(fp2);  
15.Trong hàm hiển thị các tài khoản số vốn ít, định nghĩa con trỏ tập tin để kết hợp với tập  
tin customer. Khai báo một biến cấu trúc để đọc dữ liệu của khách hàng. Câu lệnh sẽ là:  
FILE *fp;  
struct cust_st custdata;  
16.Sau khi mở tập tin ở chế độ đọc, đọc mỗi mẩu tin khách hàng và kiểm tra số vốn. Nếu nó ít  
hơn 250, in mẩu tin ra. Câu lệnh sẽ là:  
while((fread(&custdata, sizeof(struct cust_st), 1, fp))==1)  
{
if(custdata.bal<250)  
{
.
.
printf("\n%d\t%s\t%.2f", custdata.acc_no,  
custdata.cust_nm, custdata.bal);  
}
}
17.Đóng tập tin customer. Câu lệnh sẽ là:  
fclose(fp);  
Chúng ta hãy nhìn vào chương trình hoàn chỉnh.  
1. Mở chương trình soạn thảo bạn dùng để chương trình C.  
2. Tạo một tập tin mới.  
3. Gõ vào các dòng lệnh sau đây:  
#include<stdio.h>  
struct cust_st  
{
int acc_no;  
char cust_nm[30];  
float bal;  
};  
struct tran_st  
int acc_no;  
{
308  
Lập trình cơ bản C  
char trantype;  
float amt;  
};  
void main()  
{
int choice = 1;  
while(choice != 4)  
{
clrscr();  
printf("\nSelect choice from menu\n\n1. Accept  
customer details\n2. Record Withdrawal/Deposit  
transaction\n3. Print Low Balance Report\n4.  
Exit\n\nEnter choice: ");  
scanf(" %d", &choice);  
if(choice == 1)  
addcust();  
else if(choice == 2)  
rectran();  
else if(choice == 3)  
prnlowbal();  
}
}
addcust()  
{
FILE *fp;  
char flag = 'y';  
struct cust_st custdata;  
clrscr();  
if((fp = fopen("customer", "a+")) == NULL)  
{
printf("\nERROR opening customer file");  
getch();  
return;  
}
while(flag == 'y')  
{ printf("\n\nEnter Account number: ");  
scanf(" %d", &custdata.acc_no);  
printf("\nEnter Customer Name: ");  
scanf("%s", custdata.cust_nm);  
printf("\nEnter Account Balance: ");  
scanf(" %f", &custdata.bal);  
fwrite(&custdata, sizeof(struct cust_st), 1, fp);  
printf("\n\nAdd another? (y/n): ");  
scanf(" %c", &flag);  
}
fclose(fp);  
}
Quản tập tin  
309  
rectran()  
{
FILE *fp1, *fp2;  
char flag = 'y', found, val_flag;  
struct cust_st custdata;  
struct tran_st trandata;  
int size = sizeof(struct cust_st);  
clrscr();  
if((fp1 = fopen("customer", "r+w")) == NULL)  
{
printf("\nERROR opening customer file");  
getch();  
return;  
}
if((fp2 = fopen("trans", "a+")) == NULL)  
{
printf("\nERROR opening transaction file");  
getch();  
return;  
}
while(flag == 'y')  
printf("\n\nEnter Account number: ");  
{
scanf("%d", &trandata.acc_no);  
found='n';  
val_flag = 'n';  
rewind(fp1);  
while((fread(&custdata, size, 1, fp1))==1 &&  
found=='n')  
{
if(custdata.acc_no == trandata.acc_no)  
{
found = 'y';  
break;  
}
}
if(found == 'y')  
while(val_flag == 'n')  
{
{
printf("\nEnter Transaction type (D/W): ");  
scanf(" %c", &trandata.trantype);  
if(trandata.trantype!='D' &&  
trandata.trantype!='d' &&  
trandata.trantype!='W' &&  
trandata.trantype!='w')  
printf("\t\tInvalid transaction type,  
please reenter");  
else  
val_flag = 'y';  
}
val_flag = 'n';  
while(val_flag == 'n')  
{
printf("\nEnter amount: ");  
scanf(" %f", &trandata.amt);  
if(trandata.trantype=='W' ||  
trandata.trantype=='w')  
{
310  
Lập trình cơ bản C  
if(trandata.amt > custdata.bal)  
printf("\nAccount balance is  
%.2f. Please reenter withdrawal amount.", custdata.bal);  
else  
{
custdata.bal -= trandata.amt;  
val_flag = 'y';  
}
}
else  
{
custdata.bal += trandata.amt;  
val_flag = 'y';  
}
}
fwrite(&trandata, sizeof(struct tran_st), 1,  
fp2);  
fseek(fp1, (long)(-size), 1);  
fwrite(&custdata, size, 1, fp1);  
}
else  
printf("\nThis account number does not  
exist");  
}
printf("\nRecord another transaction? (y/n): ");  
scanf(" %c", &flag);  
fclose(fp1);  
fclose(fp2);  
}
prnlowbal()  
{
FILE *fp;  
struct cust_st custdata;  
char flag = 'n';  
clrscr();  
if((fp = fopen("customer", "r")) == NULL)  
{
printf("\nERROR opening customer file");  
getch();  
return;  
}
printf("\nReport on account balances below 250\n\n");  
while((fread(&custdata, sizeof(struct cust_st), 1, fp))  
== 1)  
{
if(custdata.bal < 250)  
{
flag = 'y';  
printf("\n%d\t%s\t%.2f", custdata.acc_no,  
custdata.cust_nm, custdata.bal);  
}
}
if(flag == 'n')  
Quản tập tin  
311  
printf("\nNo account balances found below 250");  
getch();  
fclose(fp);  
}
Để xem kết quả, thực hiện các bước sau đây:  
4. Lưu tập tin với tên filesI.C.  
5. Biên dịch tập tin, filesI.C.  
6. Thực thi chương trình, filesI.C.  
7. Trở về chương trình soạn thảo.  
Kết xuất của chương trình như sau:  
Select choice from menu  
1. Accept customer details  
2. Record Withdrawal/Deposit transaction  
3. Print Low Balance Report  
4. Exit  
Enter choice:  
Một mẫu kết xuất của hàm thêm vào chi tiết của khách hàng như sau:  
Enter Account number: 123  
Enter Customer Name: E.Wilson  
Enter Account Balance: 2000  
Add another? (y/n):  
Một mẫu kết xuất của hàm thêm vào chi tiết của giao dịch như sau:  
Enter Account number: 123  
Enter Transaction type (D/W): W  
Enter amount: 1000  
Record another transaction? (y/n):  
Một mẫu kết xuất của hàm hiển thị báo cáo các tài khoản vốn thấp như sau:  
Report on account balances below 250  
104  
Jones 200  
312  
Lập trình cơ bản C  
113  
120  
Sharon 150  
Paula 200  
Quản tập tin  
313  
Phần II – Trong thời gian 30 phút kế tiếp:  
1. Viết một chương trình C để hiển thị sự khác nhau giữa hai tập tin nhập vào như đối số của dòng  
lệnh. Với mỗi sự khác nhau, hiển thị vị trí tìm thấy sự khác nhau và các ký tự của hai tập tin tại vị  
trí đó. Cũng cần phải bảo đảm rằng người sử dụng đã nhập vào số lượng đối số hợp lệ. Cuối cùng,  
hiển thị tổng số sự khác nhau đã tìm thấy.  
Để làm điều này,  
a. Khai báo các biến argv và argc để nhận vào đối số tdòng lệnh.  
b. Khai báo con trỏ trỏ đến hai tập tin.  
c. Kiểm tra tính hợp lệ của argc để bảo đảm rằng đã nhập đúng số đối số.  
d. Mở hai tập tin ở chế độ đọc.  
e. Đặt một vòng lặp để đọc từng tự từ hai tập tin cho đến khi đến cuối cả hai tập tin.  
f. Nếu các ký tự là khác nhau, hiển thị chúng cùng với vị trí của chúng. Tăng số đếm sự khác  
nhau lên 1.  
g. Nếu đi đến cuối của một tập tin, in các ký tự còn lại trong tập tin kia như sự khác biệt.  
h. Kiểm tra số đếm sự khác nhau để hiển thị các thông báo thích hợp.  
i. Đóng hai tập tin.  
314  
Lập trình cơ bản C  
Bài tập tự làm  
1. Viết một chương trình C để sao chép nội dung của một tập tin vào một tập tin khác loại trừ các từ  
a, an, và the.  
2. Viết một chương trình C để nhập vào hai chuỗi số. Lưu trữ mỗi chuỗi ở hai tập tin riêng biệt. Sắp  
xếp chuỗi trong mỗi tập tin. Trộn hai chuỗi vào một, sắp xếp lưu lại chuỗi kết quả vào một tập  
tin mới. Hiển thị nội dung của tập tin mới.  
Quản tập tin  
315  
doc 11 trang Thùy Anh 26/04/2022 9320
Bạn đang xem tài liệu "Giáo trình Lập trình cơ bản C - Bài 22: Quản lý tập tin (Tiếp theo)", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

File đính kèm:

  • docgiao_trinh_lap_trinh_co_ban_c_bai_22_quan_ly_tap_tin_tiep_th.doc