【程序设计与实践】实验二:个人资金账户管理 您所在的位置:网站首页 读取最后一条记录 【程序设计与实践】实验二:个人资金账户管理

【程序设计与实践】实验二:个人资金账户管理

2024-07-17 12:39| 来源: 网络整理| 查看: 265

实验二:个人资金账户管理 题目:

阅读下列“资金账户的管理”程序,对程序进行调试、改错,并增加函数,使之符合如下具体功能。

1) 资金账户的信息统一放在*随机文件中,该随机文件包括的数据项有记录ID、发生日期、发生事件、发生金额(正的表示收入,负的表示支出)和金额。每发生一笔收支,文件要增加一条记录,并计算一次余额。 在这里插入图片描述

2) 程序实现3个功能,包括: (1) 能创建资金账户文件并添加收入或支出信息记录 (2) 能显示所有记录,得知资金账户的收支流水账; (3) 能查询最后一条记录,获知账户最后的余额。 账户文件名命名为cashbox.dat,文件部分内容如下;

cashbox.dat LongID CreateDateNote Charge Balance 1 2006-06-01 alimony 500.00 500.00 2 2006-06-08 shopping -300.00 200.00 3 2006-06-15 shopping -60.00 140.00 4 2006-06-20 workingpay 200.00 340.00 5 2006-08-01 scholarship 1000.00 1340.00

2) 增加修改资金账户的功能。输入一个记录ID,如果文件中已存在该记录,则输入新的记录信息并更新资金账户文件中相应记录的信息。 要求定义和调用函数UpdateLog(),其功能是修改资金账户记录。

3) 增加删除资金账户的功能。输入一个记录ID,如果文件中已存在该记录,则删除该记录信息。 要求定义和调用函数Deletelog(),其功能是删除资金账户记录。

注释

随机读写是按你给的地点读写,(用 fseek 等函数找地点),可以在文件的任何地方–开始处,文件尾,文件中部,前前后后地读写。顺序读写 是从文件开始处依次读,从文件尾开始依次写。 对文件的读写操作可按指定的字节号进行。即可以通过调用库函数去指定开始读或写的字节号,然后直接对该位置上的数据进行读或写操作。

“b”是二进制模式// if((fp=fopen(“cashbox.dat”,“ab+”))==NULL){ "a+"模式: 打开文件进行“读写”操作,即既可读取,又可写入 若欲操作的文件不存在,则新建文件 成功打开文件时,文件指针位于文件结尾 打开文件后,不会清空文件内原有内容 读取内容时,可以在任意位置进行,但写入内容时,只会追加在文件尾部

fp1=fopen(“cashbox.dat”,“wb+”); "w+"模式: 1.打开文件进行“读写”操作,即既可读取,又可写入。 2.若欲操作的文件不存在,则新建文件。 3.成功打开文件时,文件指针位于文件开头。 4.打开文件后,会清空文件内原有的内容。 5.无论是读取内容还是写入内容,都可在文件中任意位置进行,且进行写入操作时,会覆盖原有位置的内容。

fseek函数设置文件指针cfp的位置(从SEEK_SET开始移动size*(logcount-1)) (0L不移动)SEEK_SET文件头 SEEK_END文件尾

ftell用于得到文件位置指针当前位置相对于文件首的偏移字节数

rewind(cfp);//重设文件指针

fread(&log,size,1,cfp); /1.读取到的位置指针 2.一个对象的字节大小 3.对象个数 4.要读的目标指针/

fwrite(plog,size,logcount,cfp);

附录 #include #include #include #include #include long size; /*当前最近一次的流水号*/ struct LogData{ /*记录的结构*/ long logid; /*记录ID*/ char logdate[11]; /*记录发生日期*/ char lognote[15]; /*记录事件说明*/ double charge; /*发生费用:负表示支出,正表示收入*/ double balance; /*余额*/ }; int inputchoice()/*选择操作参数*/ { system("cls"); int mychoice; printf("\n"); printf("\n"); printf(" 程序设计与实践 实验(二) 个人资金账户管理\n"); printf("\n"); printf(" Personal Cashbox Management\n"); printf(" ============================= \n"); printf(" 1 - Add a new cash log.\n 2 - List all cash log.\n"); printf(" 3 - Query last cash log.\n 4 - Update a cash log.\n"); printf(" 5 - Delete a cash log.\n 0 - End program.\n"); printf("\n"); printf(" Enter your choice:"); scanf("%d",&mychoice); return mychoice; } long getLogcount(FILE *cfp) /*获取文件记录总数*/ { long begin,end,logcount; fseek(cfp,0L,SEEK_SET); //SEEK_SET文件头 begin=ftell(cfp); //ftell用于得到文件位置指针当前位置相对于文件首的偏移字节数 fseek(cfp,size,SEEK_END); //SEEK_END文件尾 end=ftell(cfp); logcount=(end-begin)/size -1; return logcount; } void AddNewLog(FILE *cfp) /*添加新记录*/ { struct LogData log,lastlog; long logcount; printf("Input logdate(format:2020-01-01):"); scanf("%s",log.logdate); printf("Input lognote:"); scanf("%s",log.lognote); printf("Input Charge:Income+ and expend-:"); scanf("%lf",&log.charge); logcount=getLogcount(cfp); /*获取记录数*/ if(logcount>0){ fseek(cfp,size*(logcount-1),SEEK_SET); /*fseek函数设置文件指针cfp的位置(从SEEK_SET开始移动size*(logcount-1))*/ fread(&lastlog,size,1,cfp); /*读入最后记录*/ log.logid=lastlog.logid+1; /*记录号按顺序是上次的号+1*/ log.balance=log.charge+lastlog.balance; } else{ /*如果文件是初始,记录数为0*/ log.logid=1; log.balance=log.charge; } rewind(cfp);//重设文件指针 getch(); //等待按下任意键,再继续执行下面的语句 fwrite(&log,sizeof(struct LogData),1,cfp); /*写入记录*/ fclose(cfp); } void ListAllLog(FILE *cfp) /*列出所有收支流水帐*/ { struct LogData log; long logcount; logcount=getLogcount(cfp); if(logcount>0){ /*表示有记录存在*/ fseek(cfp,0L,SEEK_SET); /*定位指针到文件开始位置,0L—不移动*/ fread(&log,size,1,cfp); /*1.读取到的位置指针 2.一个对象的字节大小 3.对象个数 4.要读的目标指针*/ printf("LogID LogDate LogNote Charge Balance\n"); while(!feof(cfp)){ //检测文件结束符,如果文件结束,则返回非0值,否则返回0 printf("%5ld %-12s %-15s %10.2lf %10.2lf\n", log.logid,log.logdate,log.lognote,log.charge,log.balance); fread(&log,size,1,cfp); } } else printf("no logs in file!\n"); printf("\n"); printf("Press any key to continue..."); system("pause"); } void QueryLastLog(FILE *cfp) /*查询显示最后一条记录*/ { struct LogData log; long logcount; logcount=getLogcount(cfp); if(logcount>0){ /*表示有记录存在*/ fseek(cfp,size*(logcount-1),SEEK_SET); /*定位最后一条记录*/ fread(&log,size,1,cfp); /*读取最后一条记录*/ printf("The last log is:\n"); /*显示最后一条记录*/ printf(" LogID:%-6ld\n LogDate:%-11s\n LogNote:%-15s\n", log.logid,log.logdate,log.lognote); printf(" Charge:%-10.2lf\n *Balance:%-10.2lf\n", log.charge,log.balance); } else printf("no logs in file!\n"); printf("\n"); printf("Press any key to continue..."); getch(); } /*函数功能:查询记录 ID 并更新账户记录*/ void Updatelog(FILE *cfp){ struct LogData log[1000],*plog=log,newlog; /*假定文件不超过1000记录*/ //plog=log数组首地址? long logcount,logid,i,index=-1; printf("Input LogID:"); scanf("%ld",&logid); /*输入要修改的记录 ID*/ /*查找帐户号是否存在,若存在则更新*/ logcount=getLogcount(cfp); /*获取记录数*/ rewind(cfp); fread(plog,size,logcount,cfp); //相当于copy?从文件中读到数组中 for(i=0;i /*已经找到*/ printf("LogID LogDate LogNote Charge Balance\n");/*显示当前记录*/ printf("%5ld %-12s %-15s %10.2lf %10.2lf\n", log[i].logid,log[i].logdate,log[i].lognote,log[i].charge,log[i].balance); index=i; break; } } rewind(cfp); if(index>=0){ printf("Input logdate(format:2020-01-01):"); scanf("%s",newlog.logdate); printf("Input lognote:"); scanf("%s",newlog.lognote); printf("Input Charge:Income+ and expend-:"); scanf("%lf",&newlog.charge); if(strcmp(log[index].lognote,newlog.lognote)!=0)//比较,如果不相同,则修改 strcpy(log[index].lognote,newlog.lognote); if(strcmp(log[index].logdate,newlog.logdate)!=0) strcpy(log[index].logdate,newlog.logdate); /*如果输入的收支额度改变,重新计算余额*/ if(newlog.charge!=log[index].charge){ newlog.balance=log[index].balance-log[index].charge+newlog.charge; /*计算新余额*/ log[index].charge=newlog.charge; /*更新收支*/ log[index].balance=newlog.balance; /*更新余额*/ /*当前记录之后的每条记录余额信息更新*/ for(i=index+1;i FILE *fp1; struct LogData log[1000],*plog=log;/*假定文件不超过 1000 记录*/ long logcount,logid,i,index=-1; printf("Input LogID:"); scanf("%ld",&logid); /*输入要删除的记录 ID*/ /*查找帐户号是否存在,若存在则更新*/ logcount=getLogcount(cfp); /*获取记录数*/ rewind(cfp); fread(plog,size,logcount,cfp); //从文件中读到数组中 for(i=0;i /*已经找到,显示当前记录*/ printf("LogID LogDate LogNote Charge Balance\n"); printf("%5ld %-12s %-15s %10.2lf %10.2lf\n", log[i].logid,log[i].logdate,log[i].lognote,log[i].charge,log[i].balance); index=i; getch(); break; } } printf("\n"); rewind(cfp); if(index>=0){ for(i=index;i /*输出当前new记录*/ printf("%5ld %-12s %-15s %10.2lf %10.2lf\n", log[i].logid,log[i].logdate,log[i].lognote,log[i].charge,log[i].balance); } getch(); fp1=fopen("cashbox.dat","wb+"); //打开文件后,会清空文件内原有的内容。 /* "w+"模式: 1.打开文件进行“读写”操作,即既可读取,又可写入。 2.若欲操作的文件不存在,则新建文件。 3.成功打开文件时,文件指针位于文件开头。 4.打开文件后,会清空文件内原有的内容。 5.无论是读取内容还是写入内容,都可在文件中任意位置进行,且进行写入操作时,会覆盖原有位置的内容。 "b"表示二进制; */ fwrite(plog,size,logcount-1,fp1);/*写回去更新*/ fclose(fp1); } else{ printf("Error logid and try another!\n"); printf("Press any key to continue..."); getch(); } } int main(void) { FILE *fp; int choice; if((fp=fopen("cashbox.dat","ab+"))==NULL){ //打开文件后,不会清空文件内原有内容 /* "a+"模式: 打开文件进行“读写”操作,即既可读取,又可写入 若欲操作的文件不存在,则新建文件 成功打开文件时,文件指针位于文件结尾 打开文件后,不会清空文件内原有内容 读取内容时,可以在任意位置进行,但写入内容时,只会追加在文件尾部 "b"表示二进制; */ printf("can not open file cashbox.dat!\n"); exit(0);//退出程序 } size=sizeof(struct LogData);//一个结构体所占的字节—52? while((choice=inputchoice())!=0){ switch(choice){ case 1: fp=fopen("cashbox.dat", "ab+"); AddNewLog(fp);break;/*添加新记录*/ case 2: fp=fopen("cashbox.dat", "ab+"); ListAllLog(fp);break;/*列出所有的收入支出情况*/ case 3: fp=fopen("cashbox.dat", "ab+"); QueryLastLog(fp);break;/*查询最后的余额*/ case 4: fp=fopen("cashbox.dat", "rb+"); Updatelog(fp);break;/*新增语句更新资金账户记录*/ case 5: fp=fopen("cashbox.dat", "rb+"); Deletelog(fp);break;/*删除一条资金账户记录*/ default: printf("Input Error.");break; } } if(fclose(fp)){//如果关闭成功返回 0,否则返回EOF(-1) printf( "Can not close the file!\n" ); exit(0);//退出程序 } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有