个人帐簿管理系统课程设计论文.docx
《个人帐簿管理系统课程设计论文.docx》由会员分享,可在线阅读,更多相关《个人帐簿管理系统课程设计论文.docx(51页珍藏版)》请在冰豆网上搜索。
个人帐簿管理系统课程设计论文
课程设计
教学院
计算机学院
课程名称
数据结构课程设计
题目
个人帐簿管理系统
专业
网络工程
班级
姓名
同组人员
指导教师
一概述
1.课程设计的目的
(1).理解和掌握该课程中的有关基本概念,程序设计思想和方法。
(2).培养综合运用所学知识独立完成课题的能力。
(3).培养勇于探索、严谨推理、实事求是、有错必改,用实践来检验理论,全方位考虑问题等科学技术人员应具有的素质。
(4).掌握从资料文献、科学实验中获得知识的能力,提高学生从别人经验中找到解决问题的新途径的悟性,初步培养工程意识和创新能力。
2.课程设计的要求
个人帐簿管理系统记录某人每月的全部收入及各项开支情况,包括食品消费,房租,子女教育费用,水电费,医疗费,储蓄等。
该系统采用了WindowsXP操作系统结合VisualC++6.0,TC2.0等软件开发,可以输入和修改某月的收支情况,可以对每月的开支从小到大进行排序,可以根据输入的月份查询每月的收支情况。
该课程设计中会频繁的使用到C语言里的文件操作的知识点,而文件操作又是我们平常的学习当中使用的比较少的地方,所以在课程设计之前我们组的成员专门花了一节课的时间重新阅读了《C程序设计教程》以及《Cprimerplus》里的文件操作的相关知识。
二总体方案设计
1.系统整体设计思路
本课程序中主要通过C语言的文件操作实现文件的读写操作来存放管理数据,里面主要包含功能函数有接收键盘输入数据、将数据写入指定文件、将.dat文件文件转换.txt文件显示出来、找到对应月份、对一个月内各项支出进行排序、修改其中一项数据以及删除整月数据。
整个系统的界面以及对各功能函数的调用都放在了主函数之中。
整个程序中一个指针变量a贯穿始终,可以使各个函数共享指针变量a所指向的内存区域的数据。
整个程序涉及到的功能较多,代码普遍较长,根据课程设计教学大纲里的要求以及我们对程序的整体设计我们将整个程序分为了6个功能,7个功能函数以及主函数来调度各个函数以来实现功能。
2.算法的整体思路
数据类型设定为:
typedefstruct{
intmonth;
intshipin;
intfangzu;
intzinv;
intshuidian;
intyiliao;
intchuxu;
intshouru;
}Infor;
为了方便使用,所以每一个变量基本上都使用了拼音。
另外为了方便查询与排序,又另外定义了
typedefstruct{
intno;
intdata;
}pType;方便排序时候使用。
整个程序流程图如下:
整个程序在主函数中由switch调用各个功能函数来执行整个程序。
3.主要特点
本程序可以在控制台里录入数据后写入文件当中,即使退出了程序,只要不删除自己所写的文件都可以随时通过程序对文件里的任意数据进行增删改查,并且可以实现对多文件的管理,在修改数据的时候我们可以对指定文件里的指定月份的指定数据项进行修改体现了修改的灵活性,在查询的时候我们可以在控制台中查询一个文件中里的一个月的数据也可以在控制台中查询指定文件里的直径月份的数据,还可以对指定文件里的指定月份的数据整项删除。
最后该程序还可以对每个月中的各项开支进行从小到大的排序。
4.具备功能
该程序可以接收键盘输入数据、将数据写入指定文件、将.dat文件文件转换为txt文件显示出来方便查看、找到对应月份、对一个月内各项支出进行排序、修改其中一项数据以及删除整月数据最后在主函数中对小组成员的各个函数进行整体的调试调用。
详细情况见下表:
voidinput(Infor*a)
该函数接受一个从主函数传过来的指针变量,将数据写入a所指向的内存区域
voidwriteinfor(Infor*a)
该函数将a所指向的内存区域的数据写入到指定的.dat文件中
voidchangeFormat()
该函数用于查询的时候将.dat文件里的数据写入到控制台中,并转化一个.txt文件显示出来,最后关闭这个文件。
函数执行完毕并删除该.txt文件
intsearch(Infor*a)
接受主函数中传来的指针变量,寻找该指针指向的内存区域中a->month与你所需要查找的month值相等的位置,使a指针刚好指向这个月的数据,若找到了标志位为1返回正确,如果没找到的话就显示为找到对应月份。
voidpaixu(Infor*a)
对指定月份里的数据项里的数据从小到大进行排序。
voidmodify(Infor*a,intmon)
对指定文件的指定月份的指定的数据项的数据进行修改
voiddelRecord(intmon)
对指定的文件的指定月份的数据整月进行删除
我在本程序中承担的主要任务是查找对应月份,查询数据或修改该月份中的一项数。
该三项功能主要解决的问题是如何在指定的文件中找到对应的数据项并对该数据项进行相应的操作。
最后在主函数中通过switch对各个功能模块进行整体调用最终实现该系统。
我所主要要解决的问题是如何使用正确的文件读写操作模式字符串来打开文件以及对指定的.dat文件读取后转换为.txt文件并最终按照以定的格式显示在屏幕上。
另外在查询函数中我们要在相应的文件中找到对应的月份,并将指针移动到这里指向该数据区域,这样的话我们就可以利用该指针变量方便的查询、修改数据,这也正是体现出指针变量使用的灵活性。
其中文件操作中fopen函数模式字符串的功能如下:
模式字符串
意义
“r”
打开已过文件,可以读取文件
“w”
打开已文件,可以写入文件,先将文件的长度截为0,如果该文件不存在则创建之
“a”
打开一个文本文件,可以写入文件,向已有文件的尾部追加内容,如果该文件不存在则先创建之
“r+”
打开一个文本文件,可以进行更新,也可以读取和写入文件
“w+”
打开已隔文本文件,可以进行更新(写入),如果该文件存在则首先将其长度截为0;如果不存在则先创建之
“a+”
打开一个文本文件,可以进行更新(读取和写入),向已有的文件的尾部追加内容,如果该文件不存在则先创建之;可以读取整个文件,但写入时只能追加内容
“rb”,”wb+”,”ab”,”ab+”,”a+b”,”wb+”,”w+b”
“ab+”,”a+b”
与前面的模式相同,只是使用二进制模式而非文本模式打开文件
三详细设计
1.changeFormat()
该函数功首先在控制台上打印一排语句提示用户输入想要查找的文件名,若该文件不存在的话该程序就会终止。
若该文件存在的话使用文件类型指针fp1指向该文件,以二进制文件读写方式打开该文件,接着我用相通的名字却用.txt后缀创建了另一个文件,并用文件类型指针fp2指向它,并在该文件中打印一些展示文字使输出结果更加好看,同时将这些文字也打印在了控制台上,最后将fp1文件指向的内容用格式化输出fprintf全部写入fp2中,最后分别关闭fp1,fp2,并将刚刚的.txt文件显示出来,同时删除刚刚创建的.txt文件。
voidchangeFormat()
{
FILE*fp1,*fp2;
Infor*a;
charfilename[100];
inti;
a=(Infor*)malloc(sizeof(Infor));
printf("请输入您要查询的数据所在的文件名(以.dat为后缀的文件名)");
scanf("%s",filename);
fp1=fopen(filename,"rb+");//以读写方式打开一个二进制文件
if(fp1==NULL)
{
printf("无法找到文件\n");
exit(0);
}
for(i=0;filename[i]!
='.';i++)
{
filename2[i]=filename[i];
}
if(filename2[i]!
='.')
{
strcat(filename2,".txt");//将filename的后缀改为.txt文件
}
fp2=fopen(filename2,"wb+");
if(fp2==NULL)
{
printf("无法创建文件\n");
return;//返回主函数
}
fputs("\n……………………………………个人帐簿管理系统……………………………………\r\n",fp2);
fputs("记录月份食品消费房租费用子女费用水电费用医疗费用储蓄费用本月收入\r\n",fp2);
fputs("-----------------------------------------------------------------------\r\n",fp2);
printf("\n记录月份食品消费房租费用子女费用水电费用医疗费用储蓄费用本月收入\n");
printf("-----------------------------------------------------------------------\n");
rewind(fp1);//使fp1指向文件开头
fread(a,sizeof(Infor),1,fp1);
while(!
feof(fp1))//从原文件.dat中读数据写入显示文件.txt中
{
printf("%7d%8d%8d%8d%8d%8d%8d%8d\n",a->month,a->shipin,a->fangzu,a->zinv,a->shuidian,a->yiliao,a->chuxu,a->shouru);
fprintf(fp2,"%7d%8d%8d%8d%8d%8d%8d%8d\r\n",a->month,a->shipin,a->fangzu,a->zinv,a->shuidian,a->yiliao,a->chuxu,a->shouru);//格式化文件输出
fread(a,sizeof(Infor),1,fp1);
}
fputs("-----------------------------------------------------------------------\r\n",fp2);
fputs("\r关闭本程序继续原程序!
\n",fp2);
fclose(fp1);
fclose(fp2);
system(filename2);//调用打开转换的文本文件
remove(filename2);
}
2.search(infor*a)
该函数功首先在控制台上打印一排语句提示用户输入想要查找的文件名,若该文件不存在的话该程序就会终止。
若该文件存在的话使用文件类型指针fp1指向该文件,以二进制文件读写方式打开该文件,接着我用相通的名字却用.txt后缀创建了另一个文件,并用文件类型指针fp2指向它,并在该文件中打印一些展示文字使输出结果更加好看,同时将这些文字也打印在了控制台上,最后将fp1文件指向的内容用格式化输出fprintf全部写入fp2中,最后分别关闭fp1,fp2,并将刚刚的.txt文件显示出来,同时删除刚刚创建的.txt文件。
intsearch(Infor*a)
{
FILE*fp1;
intmon;
intisfound=0;//标志变量,初始为0代表为找到对应的月份,若找到对应的月份这设置为1
charfilename[100];
printf("请输入文件名字(.dat文件):
");
scanf("%s",filename);
printf("请正确输入月份:
");
scanf("%d",&mon);
fflush(stdin);//清除缓冲区
fp1=fopen(filename,"rb+");
if(fp1==NULL)
{
printf("无法找到文件\n");
exit(0);
}
rewind(fp1);//将fp1指向文件头,这样更加严谨
fread(a,sizeof(Infor),1,fp1);
while(!
feof(fp1))//查询操作
{
if(a->month==mon)
{
isfound=1;
break;
}
else
{
isfound=0;
}
fread(a,sizeof(Infor),1,fp1);
}
fclose(fp1);
if(isfound)
{
returnOK;
}
else
{
printf("未找到对应的月份\n");
return1;
}
}
3.voidmodify(Infor*a,intmon)
该函数主要功能在于修改指定文件下指定月份的指定数据项,首先用fp1指向指定的文件,同时用fp2打开一个temp.dat文件。
月份是通过前面的search函数找到后,通过指针变量a”传递”过来的。
首先选择修改哪一项数据,然后输入要修改的数据的内容将其写入a指向的内存区域里对应的数据项。
此时我们用printf在控制台打印出修改后的月份的数据。
然后用指针变量b来存储从fp1文件中读取的数据,当它不是对应的月份就直接写入fp2指向的temp.dat文件中,当它是对应的月份的时候就将a指向的内存区域的数据写入fp2指向的temp.dat文件中,该过程还是一个直到fp1指向文件结尾时才结束的函数。
最后关闭fp1,fp2指向的文件,删除源文件,将temp.dat文件的名字命名为与先前文件相同的名字并在控制台上打印出修改成功的字样。
voidmodify(Infor*a,intmon)//修改数据
{
FILE*fp1,*fp2;
inti;
intmoney;
charfilename[100];
Infor*b;
b=(Infor*)malloc(sizeof(Infor));
printf("修改后的数据所要插入的文件(注意与前面的文件名一定要是一致的!
!
)");
scanf("%s",filename);
fp1=fopen(filename,"rb+");
fp2=fopen("temp.dat","wb+");//temp.dat作为临时文件
printf("你要修改哪一项数据?
(1代表食品,2代表房租,3代表子女费用,4代表水电费用,5代表医疗费用,6代表储蓄,7代表收入):
");
scanf("%d",&i);
while(i<1||i>7)
{
printf("请重新输入:
");
scanf("%d",&i);
}
printf("请将修改后的数据输入进来:
");
scanf("%d",&money);
switch(i)
{
case1:
a->shipin=money;
break;
case2:
a->fangzu=money;
break;
case3:
a->zinv=money;
break;
case4:
a->shuidian=money;
break;
case5:
a->yiliao=money;
break;
case6:
a->chuxu=money;
break;
case7:
a->shouru=money;
break;
default:
break;
}
printf("修改后的:
\n");
printf("\n记录月份食品消费房租费用子女费用水电费用医疗费用储蓄费用本月收入\n");
printf("-----------------------------------------------------------------------\n");
printf("%7d%8d%8d%8d%8d%8d%8d%8d\n",a->month,a->shipin,a->fangzu,a->zinv,a->shuidian,a->yiliao,a->chuxu,a->shouru);
rewind(fp1);
fread(b,sizeof(Infor),1,fp1);
while(!
feof(fp1))//重写数据
{
if(b->month==mon)
{
fwrite(a,sizeof(Infor),1,fp2);//修改数据
}
else
{
fwrite(b,sizeof(Infor),1,fp2);
}
fread(b,sizeof(Infor),1,fp1);
}
fclose(fp1);
fclose(fp2);
remove(filename);//删除源文件
rename("temp.dat",filename);//重命名中间文件
printf("修改数据成功!
\n");
}
4.主函数调试
主函数部分通过switch语句来对实现整个程序功能的调度。
首先case1里通过input函数将变量写入a所指向的内存区域,然后调用writeinfor函数将指针变量a所指向区域的数据写入用户自己指定的文件中。
case2是对用户指定的文件的数据进行整个文件查询,结果最终会打印在控制台中并且还会显示一个.txt文件这样更加方便更加直观。
case3中调用了search函数,并且通过标志位变量flag来接收search函数所返回的值,若flag值不是OK的话就打印出没有符合条件的记录的语句,flag是OK的话就通过指针变量a将其所指向的内存区域的数据格式化的打印在屏幕上,然后调用modify函数对该该月份的数据指定的数据项进行修改。
case4中前面部分的流程与case3还是一样的,同样是调用search函数找到指定文件里的指定月份的数据并使a指向它,最后通过指针变量a打印在屏幕上。
case5中还是通过search函数来找到指定的月份然后通过paixu函数来对指定月份的数据进行从小到大的排序,最后还是打印到控制台上。
case6中同样是通过search函数找到指定的月份,并删除这个月份的所有数据。
case7中通过函数中的exit()函数来退出整个程序。
主函数的整个流程图如算法整体思路里的函数流程图所示,在这里就省略掉了。
intmain()
{
while(TRUE)
{
intflag;//标志位,用来保存查询函数所返回的结果
intitem;//功能项目号
intmon;
Infor*a;//信息指针
a=(Infor*)malloc(sizeof(Infor));//动态分配内存空间
do{
printf("\n\t******************欢迎进入个人帐簿管理系统****************\n");
printf("\t*\t*\n");
printf("\t*\t——————主菜单——————*\n");
printf("\t*\t*\n");
printf("\t*\t1.录入数据*\n");
printf("\t*\t2.查看数据*\n");
printf("\t*\t3.修改数据*\n");
printf("\t*\t4.查询数据*\n");
printf("\t*\t5.排序数据*\n");
printf("\t*\t6.删除数据*\n");
printf("\t*\t0.退出系统*\n");
printf("\t*\t*\n");
printf("\t**********************************************************\n\n");
printf("请输入要进行的操作:
");
scanf("%d",&item);
}while(item>7||item<0);//选择功能
switch(item)
{
//录入数据
case1:
input(a);
writeinfor(a);
break;
//查看数据
case2:
changeFormat();//将dat文件转换为txt文件来进行查询
break;
//修改数据
case3:
flag=search(a);
mon=a->month;
if(flag!
=OK)printf("\n没有符合条件的记录!
\n");
else
{
printf("\n记录月份食品消费房租费用子女费用水电费用医疗费用储蓄费用本月收入\n");
printf("-----------------------------------------------------------------------\n");
printf("%7d%8d%8d%8d%8d%8d%8d%8d\n",a->month,a->shipin,a->fangzu,a->zinv,a->shuidian,a->yiliao,a->chuxu,a->shouru);
modify(a,mon);
}
break;
//查询数据
case4:
flag=search(a);
if(flag!
=OK)printf("\n没有符合条件的记录!
\n");
else{
printf("\n记录月份食品消费房租费用子女费用水电费用医疗费用储蓄费用本月收入\n");
printf("-----------------------------------------------------------------------\n");
printf("%7d%8d%8d%8d%8d%8d%8d%8d\n",a->month,a->shipin,a->fangzu,a->zinv,a->shuidian,a->yiliao,a->chuxu,a->shouru);
}
break;
//排序数据
case5:
flag=search(a);
if(flag!
=OK)
{
printf("\n没有找到符合排序条件的记录!
\n");
}
else
{
paixu(a);
}
break;
//删除数据
case