Qu n Lý T p Tin
Bài 22
ả
ậ
M c tiêu: ụ
K t thúc bài h c này, b n có th : ể ế ạ ọ
Th c hi n các thao tác trên t p tin văn b n và t p tin nh phân ậ ự ệ ả ậ ị
M và đóng t p tin ậ ở
Đ c t t p tin và ghi vào t p tin ọ ừ ậ ậ
S d ng con tr t p tin. ử ụ ỏ ậ
duy c n th n t ẩ ẽ ễ ể ư c vi c cho trong bài này đ t đ đáp ng đ ượ ế ể ặ ọ ể ượ ượ c m t cách c n th n. Các b c đ ướ ượ cu i. Bài đã đ ố hãy th c hi n theo các b ệ ự ế đ u đ n i thích c n k , d hi u và t c gi ậ ừ ầ ả c m c tiêu h c và đ có th hi u hoàn toàn v công c . Xin ụ ề ể ể ụ ẩ ứ ộ ướ ậ
Ph n I – Trong th i gian 1 gi 30 phút đ u: ờ ầ ờ ầ
ả ậ
22.1 Qu n lý t p tin trong C
ộ ấ ệ ệ ậ ấ ồ ấ ươ ố C cung c p m t giao di n đ ng nh t cho vi c qu n lý nh p và xu t. Các ph ng pháp truy ươ i pháp cho tính t b khác. Gi c p t p tin cũng gi ng nh các ph ả ư ậ ậ đ 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. ồ ả ng pháp qu n lý các thi ả ấ ả ể ậ ế ị ậ ấ
22.1.1 Đ c, ghi và truy c p d li u trong t p tin ậ ữ ệ ọ ậ
ậ ộ ố ế ử ụ ạ t m t ch ộ ả ơ customer. Chi ti ế ộ ệ ố ọ ộ ậ ậ ợ ệ đ ề c in ra. Các b c li Có m t s hàm x lý t p tin trong t p tin header stdio.h. Chúng ta hãy vi ươ 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 ươ ữ c nh p vào và l u trong m t t p tin g i là chi ti t khách hàng đ ế ủ t c a ượ ư customer. Các giao trên t p tin c ki m tra h p l các giao d ch nh g i ti n và rút ti n đ ề ậ ể ượ ư ử ề ị trans. M t báo cáo v các khách hàng có s v n d ch h p l ố ố c ghi nh n trong t p tin ậ ộ ợ ệ ượ ị t kê nh sau: th p đ ư ệ ấ ượ ậ c đ ướ ượ
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 ể ự ị ộ ự ự ệ ể ụ i dùng. Câu l nh s là: c a ng ủ ườ ệ ẽ
Qu n lý t p tin
49
ả
ậ
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); . . }
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 ở ậ ể ể ẫ ớ nh n r ng thao tác m t p tin đã đ ậ ằ customer theo ch đ append đ có th thêm các m u tin m i. Xác ở ậ ế ộ c th c hi n. Câu l nh s là: ự ượ ệ ệ ẽ
if((fp = fopen("customer", "a+")) == NULL) {
printf("\nERROR opening customer file"); getch(); return; }
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. 6. ế ấ ữ ệ ữ ệ ậ Câu l nh s là: ệ ậ ẽ
fwrite(&custdata, sizeof(struct cust_st), 1, fp);
customer sau khi nh p d li u. Câu l nh s là: 7. Đóng t p tin ậ ậ ữ ệ ệ ẽ
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 ị trans. Và đ nh nghĩa bi n c u trúc đ nh p vào d li u c a giao ỏ ể ỏ ế ậ ữ ệ ế ể ủ ấ ậ ậ ị customer và t p tin ế d ch và đ 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. ậ ả ợ ở nh t, trong khi t p tin customer ph i m đ đ c và c p M hai t p tin theo ch đ thích h p. T p tin ậ ế ộ ệ ẫ ả ở ể ọ trans ph i cho phép thêm các m u tin m i. Câu l nh s là: ẽ ậ ậ ậ ớ
50
L p trình c b n C
ơ ả
ậ
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; }
10. Nh p vào s tài kho n cho giao d ch và b o đ m r ng nó 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ó ả ả ả i trong tài kho n. ậ ố ớ ả ạ 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 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à: ệ ậ ớ ẽ
Qu n lý t p tin
51
ả
ậ
fwrite(&trandata, sizeof(struct tran_st), 1, fp2); fseek(fp1, (long)(-size), 1);
fwrite(&custdata, size, 1, fp1);
ố ằ ư ả ủ ể ẫ ọ ủ ậ ỏ ậ ự ệ ậ c đ t l ả ằ ở ẽ ượ ố ủ ẫ ậ đây cu i c a m u tin c n c p nh t. Con tr t p tin s đ Ở ỏ ậ ộ ố 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ì v y, con tr t p tin c a t p tin ủ ị ặ ạ i customer ph i n m ậ ầ v trí v đ u c a m u tin s d ng hàm fseek(). ứ size là 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 có s v n ít, đ nh nghĩa con tr t p tin đ k t ố ố customer. Khai báo m t bi n c u trúc đ đ c d li u c a khách hàng. ấ ị ể ọ ữ ệ ủ ả ộ ế h p v i t p tin ớ ậ ợ 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. ươ ỉ
ng trình so n th o mà b n dùng đ gõ ch ng trình C. ở ươ ể ạ ả ạ ươ
1.M ch
2. T o m t t p tin m i. ộ ậ ớ ạ
3. Gõ vào các dòng l nh sau đây: ệ
#include
struct cust_st { int acc_no;
52
L p trình c b n C
ơ ả
ậ
char cust_nm[30]; float bal; };
struct tran_st { int acc_no;
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); }
Qu n lý t p tin
53
ả
ậ
fclose(fp);
}
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';
54
L p trình c b n C
ơ ả
ậ
} val_flag = 'n'; while(val_flag == 'n') { printf("\nEnter amount: "); scanf(" %f", &trandata.amt);
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; 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) {
Qu n lý t p tin
55
ậ
ả
if(custdata.bal < 250) flag = 'y'; { printf("\n%d\t%s\t%.2f", custdata.acc_no, custdata.cust_nm, custdata.bal); }
} if(flag == 'n') printf("\nNo account balances found below 250");
getch();
fclose(fp); }
c sau đây: Đ xem k t qu , th c hi n các b ả ự ệ ể ế ướ
4. L u t p tin v i tên filesI.C. ư ậ ớ
5. Biên d ch t p tin, filesI.C. ậ ị
ng trình, filesI.C. 6. Th c thi ch ự ươ
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 có v n th p nh sau: ấ ủ ư ế ể ả ấ ẫ ộ ố ị
56
L p trình c b n C
ơ ả
ậ
Report on account balances below 250
Qu n lý t p tin
57
ậ
ả
104 113 120 Jones 200 Sharon 150 200 Paula
Ph n II – Trong th i gian 30 phút k ti p: ế ế ờ ầ
1. Vi ế ể ể ậ ậ ươ ớ ấ ự ị i s d ng đã nh p vào s l ố ố ủ ng trình C đ hi n th s khác nhau gi a hai t p tin nh p vào nh là đ i s c a ữ c a hai t p ậ ự ủ ố ố ợ ng đ i s h p ị ự ể ả ị ằ ậ . Cu i cùng, hi n th t ng s s khác nhau đã tìm th y. ư 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 tin t ố ượ l ệ t m t ch ộ ệ i v trí đó. Cũng c n ph i b o đ m r ng ng ạ ị ố ỗ ự ầ ị ổ ườ ử ụ ấ ả ả ố ự ể
58
L p trình c b n C
ơ ả
ậ
Đ làm đi u này, ể ề dòng l nh. ậ ể ố ố ừ ệ ậ c a argc đ b o đ m r ng đã nh p đúng s đ i s . ố ố ố ậ ằ ả ậ ố ả ế ế ậ ộ a. Khai báo các bi n argv và argc đ nh n vào đ i s t ế b. Khai báo con tr tr đ n hai t p tin. ỏ ỏ ế c. Ki m tra tính h p l ợ ệ ủ ể ả d. M hai t p tin ch đ đ c. ở ế ộ ọ e. Đ t m t vòng l p đ đ c t ng ký t hai t p tin cho đ n khi đ n cu i c hai t p tin. ặ ể ọ ừ là khác nhau, hi n th chúng cùng v i v trí c a chúng. Tăng s đ m s f. N u các ký t ậ ố ế ể ở ặ ế t ự ừ ị ớ ị ủ ự ể ự 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 là 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. ố ế ậ
Bài t p t làm ậ ự
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 ươ ộ ậ ộ ậ ạ ừ ủ ể ộ
1. Vi
ế các t t m t ch ộ ừ a, an, và the.
Qu n lý t p tin
59
ậ
ả
ng trình C đ nh p vào hai chu i s . L u tr m i chu i t m t ch ộ ậ ậ ệ t. i chu i k t qu vào ỗ ố ư ỗ ữ ỗ ế ộ ắ hai t p tin riêng bi ỗ ế ả 2. Vi ế ắ ế ộ ậ ỗ ở ể 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 và l u l ộ ỗ ậ ư ạ m t t p tin m i. Hi n th n i dung c a t p tin m i. ủ ậ ị ộ ươ ỗ ớ ể ớ