帐目管理系统的设计与实现.docx
《帐目管理系统的设计与实现.docx》由会员分享,可在线阅读,更多相关《帐目管理系统的设计与实现.docx(32页珍藏版)》请在冰豆网上搜索。
帐目管理系统的设计与实现
一设计要求……………………………………………………………2
二设计作用与目的……………………………………………………2
三运行环境及工具软件………………………………………………2
3.1硬件环境…………………………………………………………3
3.2软件环境…………………………………………………………3
四系统设计……………………………………………………………3
4.1系统总体设计…………………………………………………3
4.2程序设计组成框图、流程图…………………………………3
4.3各模块具体设计………………………………………………5
4.3.1主函数模块设计…………………………………………5
4.3.2创建函数模块…………………………………………6
4.3.3查看函数模块…………………………………………8
4.3.4开户函数模块…………………………………………8
4.3.5销户函数模块…………………………………………10
4.3.6修改帐目函数模块………………………………………11
4.3.7查询函数模块…………………………………………12
五源程序设计……………………………………………………………14
六实验调试结果…………………………………………………………26
七设计中的问题及解决方法……………………………………………29
八设计心得……………………………………………………………29
九参考文献……………………………………………………………30
帐目管理系统的设计与实现
一、设计要求
此处的账目管理是整个银行业务中的一小部分,主要包括借款、还款、存款业务。
同时,通过帐目管理系统的设计,运用计算机软件软件基础所学的知识,提高编程兴趣与编程思路,合理的运用资料,实现理论与实际相结合。
(1)为了管理账户,设置两个单链表:
一是账户基本信息,包括账户的账号、姓名、身份证号、建账日期等信息;另一个是账户余额,包括账户的账号和当前余额两项数据。
(2)本程序能够执行账户的开户、借款、还款、存款、清户(删除)等操作,而且能够实现对账户信息的查询统计功能、按借款户的余额从大到小排序功能、按存款户的余额从大到小排序功能和按开户日期从小到大排序功能等。
(3)开新户时,用户只输入姓名、身份证号、金额、日期四个数据,由程序自动生成帐号并通知用户,并将相关数据同时插入上述两个链表中;
(4)余额为负数表示借款额,为正数表示存款额。
(5)能够按账号查询账户的基本信息和当前余额,能够列出最大借款额账户和最大存款额账户的基本信息和当前余额。
(6)程序能够统计当前帐户个数,当前借款总额、当前还款总额以及借款总额与存款总额的差额。
(7)收集资料,全面分析课题,分解问题,形成总体编程思路;
(8)深入分析各个小问题,编写各部分程序模块;
(9)对于设计中用到的关键函数,要联系问题进行具体介绍;
(10)上机调试,确保程序能正确运行,完成设计报告,并进行答辩。
二、设计作用与目的
(1)通过设计,强化C语言的运用及C语句的准确掌握;
(2)通过设计,加强我们对计算机软件软件基础知识的理解和运用;
(3)通过设计,掌握设计软件一般方法,了解软件设计的一般思路;
(4)通过设计,锻炼撰写报告的水平。
三、运行环境及工具软件
3.1硬件环境
设备:
采用Intel应用服务器
运行时内存要求:
1MB;
安装所需硬盘:
2MB;
3.2软件环境
操作系统:
Windows2000/XPista
工具软件:
MyTC
四、系统设计
4.1系统总体设计
此银行帐目管理系统包括六个模块,分别为创建一个空账目、显示账目信息、添加新账目、删除账目信息、修改账目信息、查找所需账目信息。
其中添加新账目包含姓名、身份证号、金额、日期四个数据的输入。
修改账目信息还包含了借款、存款、取款功能。
查询功能包含查询所存有的账户个数、查询最大存款户、查询最大借款户。
功能模块图如图1所示。
4.2程序设计组成框图、流程图
4.3各模块具体设计
本程序按要求设计一个账目管理系统,编译器为:
myTC。
程序源文件名为zhangmu.c。
程序入口为main()函数:
先由fopen()函数创建一个存储账目信息的文档:
fopen("D:
\\account.txt","r+");由于进行的“r+“操作,首先在D盘创建一个account.txt文件。
4.3.1主函数模块设计
主函数用到函数为:
fopen(打开文件)
相关函数
open,fclose
表头文件
#include
定义函数
FILE*fopen(constchar*path,constchar*mode);
函数说明
参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态。
mode有下列几种形态字符串:
r打开只读文件,该文件必须存在。
r+打开可读写的文件,该文件必须存在。
w打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。
若文件不存在则建立该文件。
w+打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。
若文件不存在则建立该文件。
a以附加的方式打开只写文件。
若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。
a+以附加方式打开可读写的文件。
若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。
由于Dos窗口显示有限,所以限制账目数量为15个。
本程序包含6大功能模块:
1-创建一个空账目;
2-显示账目信息;
3-添加新账目;
4-删除账目信息;
5-修改账目信息;
6-查找所需账目信息;
6-推出程序;
为了管理账户,设置两个单链表:
一是账户基本信息,包括账户的账号、姓名、身份证号、建账日期等信息;另一个是账户余额,包括账户的账号和当前余额两项数据。
本程序只创建了一个单链表:
structbankdata{/*定义一个结构体*/
intnum;/*账户的账号*/
charname[20];/*姓名*/
charperson_num[19];/*身份证号*/
floatbalance;/*金额*/
intestablishtime;/*日期*/
}
所以在对账户的余额的操作功能上有教大的欠缺,日后定将进一步完善此项功能。
4.3.2创建函数模块
1-create(FILE*ptr)/*创建具有结构体的空文档*/
structbankdatadata={-1,"NONAME","NONUM",0,0};对结构体进行初始化操作,即创建一个空账目。
for(num=0;num<=15;num++){}通过for循环限制账目数量。
本功能模块用到的函数有:
fseek(移动文件流的读写位置)
相关函数
rewind,ftell,fgetpos,fsetpos,lseek
表头文件
#include
定义函数
intfseek(FILE*stream,longoffset,intwhence);
函数说明
fseek()用来移动文件流的读写位置。
参数stream为已打开的文件指针,参数offset为根据参数whence来移动读写位置的位移数。
参数
whence为下列其中一种:
SEEK_SET从距文件开头offset位移量为新的读写位置。
SEEK_CUR以目前的读写位置往后增加offset个位移量。
SEEK_END将读写位置指向文件尾后再增加offset个位移量。
当whence值为SEEK_CUR或SEEK_END时,参数offset允许负值的出现。
下列是较特别的使用方式:
1)欲将读写位置移动到文件开头时:
fseek(FILE*stream,0,SEEK_SET);
2)欲将读写位置移动到文件尾时:
fseek(FILE*stream,0,0SEEK_END);
返回值
当调用成功时则返回0,若有错误则返回-1,errno会存放错误代码。
附加说明
fseek()不像lseek()会返回读写位置,因此必须使用ftell()来取得目前读写的位置。
fwrite(将数据写至文件流)
相关函数
fopen,fread,fseek,fscanf
表头文件
#include
定义函数
size_tfwrite(constvoid*ptr,size_tsize,size_tnmemb,FILE*stream);
函数说明
fwrite()用来将数据写入文件流中。
参数stream为已打开的文件指针,参数ptr指向欲写入的数据地址,总共写入的字符数以参数size*nmemb来决定。
Fwrite()会返回实际写入的nmemb数目。
返回值
返回实际写入的nmemb数目。
4.3.3查看函数模块
1-view(FILE*ptr)/*查看文档内容*/
本功能模块用到的函数有:
fseek(FILE*stream,longoffset,intwhence);
fread(从文件流读取数据)
相关函数
fopen,fwrite,fseek,fscanf
表头文件
#include
定义函数
size_tfread(void*ptr,size_tsize,size_tnmemb,FILE*stream);
函数说明
fread()用来从文件流中读取数据。
参数stream为已打开的文件指针,参数ptr指向欲存放读取进来的数据空间,读取的字符数以参数size*nmemb来决定。
Fread()会返回实际读取到的nmemb数目,如果此值比参数nmemb来得小,则代表可能读到了文件尾或有错误发生,这时必须用feof()或ferror()来决定发生什么情况。
返回值
返回实际读取到的nmemb数目。
4.3.4开户函数模块
2-add(FILE*ptr)/*添加一个帐目*/
添加账目,输入用户操作,
程序设计要求:
开新户时,用户只输入姓名、身份证号、金额、日期四个数据,由程序自动生成帐号并通知用户,并将相关数据同时插入上述两个链表中;
本程序账号由人工手动输入。
其余项目也有人工输入。
fseek(ptr,num*sizeof(structbankdata),SEEK_SET);
↓
fread(&data,sizeof(structbankdata),1,ptr);
↓
Scanf();
↓
fseek(ptr,data.num*sizeof(structbankdata),SEEK_SET);
↓
fwrite(&data,sizeof(structbankdata),1,ptr);
↓
实现对数据的输入,及存储。
通过函数嵌套操作实现对用户身份证号码的格式化操作。
getperson_num(char*person_num)/*函数功能:
读取用户身份证号码(15位或者18位)*/
4.3.5销户函数模块
3-delete(FILE*ptr)/*删除一个帐目*/
通过本功能实现销户操作,销户条件为用户姓名。
for(num=0;num<=15;num++)
{
fseek(ptr,num*(sizeof(structbankdata))+sizeof(int),SEEK_SET);
fread(name2,20,1,ptr);
if(strcmp(name1,name2)==0)num1[num]=num;
}
对输入用户进行查找,并与账目内容进行比较。
通过对num2的值进行判断,实现对不同账号下的同一用户进行操作,对未找到用户的提示。
4.3.6修改帐目函数模块
4-modify(FILE*ptr){}/*修改帐目*/
程序设计要求:
本程序能够执行账户的借款、还款、存款操作。
由于单链表在功能实现上的限制,只能通过本功能对三项操作实现同一数据的修改操作。
输入余额为负数表示借款额,为正数表示存款额。
本功能对程序的综合能力要求较高,时间有限,待以后进一步完善。
4.3.7查询函数模块
5-research(FILE*ptr)/*对所需账目内容进行查询*/
模块功能流图如下
打开界面,进入查询操作:
图6查询系统界面
查询功能包含三项子功能:
"0-count\n"/*查询所存有的账户个数*/
"1-Themax.depositoraccount\n"/*查询最大存款户*/
"2-Themax.borrowingaccount\n"/*查询最大借款户*/
"3-quite\n"/*退出查询*/
能够实现对账户信息的查询统计功能、按借款户的余额从大到小排序功能、按存款户的余额从大到小排序功能和按开户日期从小到大排序功能等。
能够按账号查询账户的基本信息和当前余额,能够列出最大借款额账户和最大存款额账户的基本信息和当前余额。
当前借款总额、当前还款总额以及借款总额与存款总额的差额。
本程序通过函数嵌套操作,应该可以很好的实现大部分功能,但是,由于指针参数传递过程中,程序调用总出现问题,个人对指针的学习掌握还不够熟练,所以通过在同一模块下的判断语句进行选项操作
1-操作和2-操作都是用选择排序法,分别找出最大存款户和最大借款户。
在冒泡排序、选择排序、快速排序、插入排序等当中选择排序最易理解,运行速度也比较快。
所以用选择排序法进行查找操做。
五、源程序设计
#include
#include
structbankdata{/*定义一个结构体*/
intnum;/*账户的账号*/
charname[20];/*姓名*/
charperson_num[19];/*身份证号*/
floatbalance;/*金额*/
intestablishtime;/*日期*/
}
create(FILE*ptr)/*创建具有结构体的空文档*/
{
intnum;
structbankdatadata={-1,"NONAME","NONUM",0,0};
for(num=0;num<=15;num++){
fseek(ptr,num*sizeof(structbankdata),SEEK_SET);
fwrite(&data,sizeof(structbankdata),1,ptr);
}
printf("Blankaccountshavebeencreatedcomplete\n");
}
view(FILE*ptr)/*查看文档内容*/
{
intnum;
structbankdatadata;
clrscr();/*功能:
清除文本模式窗口清屏的意思就是把之前显示出的文字字符去掉*/
printf("theaccountnum,theaccountperson_name,theperson_num,theblankdata,theestableshtime\n");
for(num=0;num<15;num++){
fseek(ptr,num*sizeof(structbankdata),SEEK_SET);
fread(&data,sizeof(structbankdata),1,ptr);
printf("%-10d%-16s%-20s%-10f%-15d\n",data.num,data.name,data.person_num,data.balance,data.establishtime);
}
}
add(FILE*ptr)/*添加一个帐目*/
{
intnum;
structbankdatadata;
printf("Enternewaccountnumber(0-15):
\n");
scanf("%d",&num);
fseek(ptr,num*sizeof(structbankdata),SEEK_SET);
fread(&data,sizeof(structbankdata),1,ptr);
if(data.num!
=-1)
printf("Account%dalreadycontainsinformaton.\n",num);
else{
printf("Entername.\n");
scanf("%s",data.name);
printf("pleaseputintotheperson_num:
");
getperson_num(data.person_num);
printf("Enterbalance.\n");
scanf("%f",&data.balance);
printf("Enterestablishtime.\n");
scanf("%d",&data.establishtime);
data.num=num;
}
fseek(ptr,data.num*sizeof(structbankdata),SEEK_SET);
fwrite(&data,sizeof(structbankdata),1,ptr);
}
getperson_num(char*person_num)/*函数功能:
读取用户身份证号码(15位或者18位)*/
{
do{
inti,mark;
charch;
for(i=0;;i++)
{/*输入有效性判断(只能是数字)*/
if((ch=getchar())!
='\n')
{
if(ch<='9'&&ch>='0')
{
person_num[i]=ch;
}
else
{break;
}
}else{break;}
}
person_num[i]='\0';
if(strlen(person_num)!
=15&&strlen(person_num)!
=18)
printf("IDnumbercanonlybe15,or18-bit,theperson_numshouldbeanum!
\n");
else
break;
}while
(1);/*循环以保证读入数据有效*/
}
delete(FILE*ptr)/*删除一个帐目*/
{
intnum,num2;
intnum1[16]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
charname1[20];
charname2[20];
structbankdatablankdata={-1,"NONAME","NONUM",0,0};
structbankdatadata;
printf("Enterdeletename.\n");
scanf("%s",name1);
for(num=0;num<=15;num++)
{
fseek(ptr,num*(sizeof(structbankdata))+sizeof(int),SEEK_SET);
fread(name2,20,1,ptr);
if(strcmp(name1,name2)==0)num1[num]=num;
}
for(num=0,num2=0;num<=15;num++)
{
if(num1[num]!
=-1)
{
fseek(ptr,num*sizeof(structbankdata),SEEK_SET);
fread(&data,sizeof(structbankdata),1,ptr);
printf("%-10d%-16s%-20s%-15f%-15d\n",data.num,data.name,data.person_num,data.balance,data.establishtime);
num2++;
}
}
if(num2>1){
printf("Whichaccountdoyouwanttodelete?
\n");
scanf("%d",&num);
fseek(ptr,num*sizeof(structbankdata),SEEK_SET);
fwrite(&blankdata,sizeof(structbankdata),1,ptr);
}
if(num2==1){
fseek(ptr,data.num*sizeof(structbankdata),SEEK_SET);
fwrite(&blankdata,sizeof(structbankdata),1,ptr);
}
if(num2==0)printf("Thereisnoyourname.\n");
}
modify(FILE*ptr)/*修改帐目*/
{
intnum,num2;
intnum3[16]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
floatnum1;
charname1[20];
charname2[20];
structbankdatadata;
printf("Entermodifyname.\n");
scanf("%s",name1);
for(num=0;num<=15;num++)
{
fseek(ptr,num*(sizeof(structbankdata))+sizeof(int),SEEK_SET);
fread(name2,20,1,ptr);
if(strcmp(name1,name2)==0)num3[num]=num;
}
for(num=0,num2=0;num<=15;num++){
if(num3[num]!
=-1)
{
fseek(ptr,num*sizeof(structbankdata),SEEK_SET);
fread(&data,sizeof(structbankdata),1,ptr);
printf("%-10d%-16s%-10f%-10d\n",data.num,