资源描述
数据结构课程设计报告
兰州理工大学
专业班级:
题 目:
姓 名:
学 号:
指导教师:
个人帐簿管理系统
目录
摘 要 1
1绪论 1
2系统分析 1
2.1 功能需求 1
2.2数据需求 1
2.3 性能需求 2
3总体设计 2
3.1系统设计方案 2
3.2功能模块设计 2
4详细设计 3
4.1录入数据模块 3
4.2修改数据子模块 4
4.3查询数据子模块 5
4.4排序数据子模块 6
6
4.6删除数据子模块 7
5调试与测试 8
5.1 调试 8
5.2 测试 8
6结论 9
结束语 9
参考文献 9
附录1-用户手册 10
附录2-源程序 13
38
摘 要
个人帐簿管理系统的开发是为了方便个人记录每月的全部收入及开支情况,包括食品消费,房租,子女教育费用,水电费,医疗费,储蓄等。并进行查询和排序等。主要实现以下功能:
(1) 记录月份以及每月的食品消费,房租,子女教育费用,水电费,医疗费,储蓄等内容。
(2) 要求该系统能查看该数据并进行修改和查询等。
(3) 并用冒泡法进行排序以及能进行内容的删除。
报告从系统分析,总体设计,详细设计,调试与测试方面进行描述和介绍。
关键词:个人帐簿管理系统;扩充;修改;删除。
前言
当今社会是个劳逸结合的社会,计算机在人们的生活中越来越重要,个人账簿管理的开发给大众的生活平添了方便。个人账簿管理系统是一个比较普遍的管理系统,它的存在方便个人记录每月的全部收入及开支情况。
根据课程设计任务书要求,个人帐簿管理系统记录某人每月的全部收入及各项开支情况,包括食品消费,房租,子女教育费用,水电费,医疗费,储蓄等。进入系统后可以输入和修改某月的收支情况,可以对每月的开支从小到大进行排序,可以根据输入的月份查询每月的收支情况。另外要求建立一个文件,包括某人5个月的收支情况,能对文件中的信息进行扩充(追加),修改和删除;完成对每月的开支排序,以及完成系统查询功能。
可进行功能的适当扩充。
2系统分析
2.1 功能需求
个人帐簿管理系统要求记录某人每月的全部收入及各项开支情况,包括食品消费,房租,子女教育费用,水电费,医疗费,储蓄等并能进行修改,查询,排序,删除等功能。
2.2数据需求
系统主要处理的是个人帐簿信息,因此其输入和输出都与此相关。
(1) 输入数据:月份和食品消费,房租,子女教育费用,水电费,医疗费,储蓄等数据。
(2) 输出数据:月份和食品消费,房租,子女教育费用,水电费,医疗费,储蓄等的数据。
2.3 性能需求
本系统主要需要达到记录某人每月的全部收入及各项开支情况,包括食品消费,房租,子女教育费用,水电费,医疗费,储蓄等并能进行修改,查询,排序,删除等功能。
3总体设计
3.1系统设计方案
(1) 菜单
本系统根据需要主要设计了6个菜单,分别为
①录 入 某 月 账 单 数 据
②查 看 某 月 账 单 数 据
③修 改 某 月 账 单 数 据
④查 询 某 月 账 单 数 据
⑤排 序 某 月 账 单 数 据
⑥退 出 系 统
(2) 文件保存方式
系统需要保文件,文件存储月份和食品消费,房租,子女教育费用,水电费,医疗费,储蓄等数据。
(3) 数据类型
系统定义了数组,结构体等类型,存储月份和食品消费,房租,子女教育费用,水电费,医疗费,储蓄等信息。
(4) 算法设计
系统中主要排序算法(冒泡排序)。
数据流图
编辑员
录入员
某月的收支 待修改信息
个人账簿管理系统
修改后信息
符合要求条目
检索条件 查询者
个人账簿文件
录入个人月账单
修改个人月账单
某月的收支 待修改信息
查询检索条目是否
与现有数据匹配
检所条件
符合要求条目
3.2功能模块设计
根据分析,系统主要设计了6个模块,分别是:录入数据模块,查看数据模块,修改数据模块,查询数据模块,排序数据模块,删除数据模块;功能模块图如图1所示。
图1功能模块图
(1)录入某月账单数据
录入数据模块把输入的信息存储到文件里,为以下操作提供数据。
(2)查看某月账单数据
查看数据模块是输入要执行的操作,打开文件,查看帐户里面的信息
(3)修改某月账单数据
修改数据模块是输入要修改的月份,打开文件,找到该月的信息,把新输入的信息复制给原有信息,已达到修改的目的。
(4)查询某月账单数据
查询数据模块是打开文件,输入要查看的月份,就将输出该月的信息。
(5)排序某月账单数据
排序数据模块是用冒泡排序,把某月份的费用从小到大排列。
(6)删除数据
删除数据模块是用链表把其中某月删除。
4详细设计
4.1录入数据模块
录入主要通过scanf函数实现。具体程序实现流程如图2所示。
图2
输入月份和食品消费,房租,子女教育费用,水电费,医疗费,储蓄等数据。
4.2修改数据子模块
修改文件中的信息,具体程序实现流程如图4所示。
图3
输入月份首先判断文件中是否有该信息,没有,输出没有符合条件的记录,有,输出该信息,再进行修改;即重新输入月份和食品消费,房租,子女教育费用,水电费,医疗费,储蓄等数据。
4.3查询数据子模块
查询某月的信息,具体程序实现流程如图5所示。
图4
输入要查询的月份,首先判断文件中是否有该信息,没有,输出无法找到该文件,有,输出该信息。
4.4排序数据子模块
排序某月的所有费用,具体程序实现流程如图6所示;
图5
冒泡排序:即第1个数与第2个数比较,若第1个大,就与第2个数交换;若第2个数大,就不交换;继续第2个与第3个比较,。。。。,直到比较完为止。
4.6删除数据子模块
删除某月的信息,具体程序实现流程如图7所示。
图6
输入要删除的月份,若文件中没有该信息,输出无法找到该文件,若文件中有该信息,输出请选择要删除的月份,输入月份,利用链表的知识删除该月份。
5调试与测试
5.1 调试
调试过程主要是运行编制好的程序,然后遇到错误后根据系统的提示,找到相关的问题所在。以解决问题。
(1) 系统提示的错误:函数没有起到作用,跟踪发现根本就没有结果,最后发现这个语句根本就没有被调用。
(2) 调试过程中遇到了储存内容重复的错误。经多次实验后得得出是系统的问题,这将有待改进。
5.2 测试
软件测试是软件生存期中的一个重要阶段,是软件质量保证的关键步骤从用户的角度来看,普遍希望通过软件测试暴露软件中隐藏的错误和缺陷,所以软件测试应该是“为了发现错误而执行程序的过程”。或者说,软件测试应该根据软件开发各阶段的规格说明和程序的内部结构而精心设计一批测试用例(即输入数据及其预期的输出结果),并利用这些测试用例去运行程序,以发现程序错误或缺陷。过度测试则会浪费许多宝贵的资源。到测试后期,即使找到了错误,然而付出了过高的代价。
(1)输入正确的数:
输入数据1:1 2 3 4 5 6 7 8
预期结果:1 2 3 4 5 6 7 8
运行结果:1 2 3 4 5 6 7 8
说明:远行正确。
(2)输入错误的数:
输入数据2:15 3 4 5 6 7 8 9
预期结果:15 3 4 5 6 7 8 9
运行结果:15 3 4 5 6 7 8 9
说明:远行错误。
6结论
经过两周的课程设计,个人帐簿管理系统基本完成,实现了任务书中的所有要求。这对不熟悉程序的人来说操作起来也不是那么轻松上手,所以还有改进的地方,相信再以后,一定会写出更完善的程序
结束语
为期二个礼拜的数据结构课程设计终于顺利完成,在这期间真正的学到了一些经验,能够熟练的掌握一些C语言的编程思路及数据结构中的一些算法,能够熟练的运用学到的函数,学会了如何调试报告并加以改正,并知道了在输入信息时也要认真看清是何类型。学到课本或一些理论中学不到的知识,这才达到了实践的目的,当程序经过多次调试,成功运行的时候,心里是激动的,这种成就感是前所未有的,也让大学生活显得不那么平常,格外的充实。
参考文献
[1] 谭浩强.C语言程序设计(第三版).清华大学出版社,2007
[2] 姜灵芝,余健.C语言课程设计案例精编.清华大学出版社,2008
[3] 网上相关资料
附录1-用户手册
(1)录入数据
(2)查看数据
(3)修改数据
(4)查询数据
(5)排序数据
(6)删除数据
附录2-源程序
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <windows.h>
//文件保存路径
#define FilePath1 "Myfile.dat"
#define FilePath2 "Myfile.txt"
//查询用声明
#define Status int//宏定义
#define OK 1//宏定义
#define Error 0//宏定义
#define NotFound 2//宏定义
typedef struct {
int month;//月份
int spxf;//食品消费
int fzfy;//房租费用
int znjy;//子女教育费用
int sdfy;//水电费用
int ylfy;//医疗费用
int cxfy;//储蓄费用
int srfy;//收入费用
} Infor;
typedef struct {// 查询用自定义数据类型
int no;
int data;
}pType;
void menu(void); //菜单
void input(Infor *newI); //接收键盘输入
void writeinfor(Infor *newI);//向文件内写入内容
void changeFormat(void );//将dat格式文件转换为txt文件
Status search(Infor *a);//查询函数[返回查询的结果及查询的状态]
void paixu(Infor *a);//对查询据结果排序
void modify(Infor *a,int mon);//修改数据
void delRecord(int mon);//删除数据
void main()//主函数
{
while(1)
{
menu();//函数调用
}
}
void menu(void)//菜单
{
int item;//定义整型
int mon;//定义整型
Infor *a;
a=(Infor *)malloc(sizeof(Infor));
do{
printf("\n\t\t…………个人帐簿管理系统设计…………\n\n");//输出
printf("\t\t 1.$录 入 某 月 数 据$\n");//输出
printf("\t\t 2.$查 看 录 入 数 据$\n");//输出
printf("\t\t 3.$修 改 某 月 数 据$\n");//输出
printf("\t\t 4.$查 询 某 月 数 据$\n");//输出
printf("\t\t 5.$排 序 某 月 数 据$\n");//输出
printf("\t\t 6.$删 除 某 月 数 据$\n");//输出
printf("\t\t 0.$***退 出 系 统***$\n");//输出
printf("\t\t………………………………………………\n\n");//输出
printf("请输入要进行的操作: " );//输出
scanf("%d",&item);//输入
}while(item>6 || item<-1);
switch(item)
{ //退出程序
case 0: getchar();//保存界面
getchar();//保存界面
exit(1);
break;//结束
//录入数据
case 1: input(a);//函数调用
writeinfor(a);//函数调用
break;//结束
//查看数据
case 2: changeFormat();//函数调用
break;//结束
//修改数据
case 3: item=search(a);//复制
mon=a->month;//复制
if (item!=OK) printf("\n没有符合条件的记录!\n"); //判断输出
else
{
printf("\n记录月份 食品消费 房租费用 子女费用 水电费用 医疗费用 储蓄费用 本月收入 \n");//输出
printf("----------------------------------------------------------------------- \n");//输出
printf("%7d %8d %8d %8d %8d %8d %8d %8d\n",a->month,a->spxf,a->fzfy,a->znjy,a->sdfy,a->ylfy,a->cxfy,a->srfy);//输出
input(a);//函数调用
modify(a,mon);//函数调用
}
break;//结束
//查询数据
case 4: item=search(a);//复制
if (item!=OK) printf("\n没有符合条件的记录!\n");//判断输出
else{
printf("\n记录月份 食品消费 房租费用 子女费用 水电费用 医疗费用 储蓄费用 本月收入 \n");//输出
printf("----------------------------------------------------------------------- \n");//输出
printf("%7d %8d %8d %8d %8d %8d %8d %8d\n",a->month,a->spxf,a->fzfy,a->znjy,a->sdfy,a->ylfy,a->cxfy,a->srfy);//输出
}
break;//结束
//排序数据
case 5: item=search(a);//复制
if (item!=OK) printf("\n没有符合条件的记录!\n"); //判断输出
else
paixu(a);//函数调用
break;//结束
//删除数据
case 6:
item=search(a);//复制
mon=a->month;//复制
if (item!=OK) printf("\n没有符合条件的记录!\n"); //判断输出
else
{
printf("\n记录月份 食品消费 房租费用 子女费用 水电费用 医疗费用 储蓄费用 本月收入 \n");//输出
printf("----------------------------------------------------------------------- \n");//输出
printf("%7d %8d %8d %8d %8d %8d %8d %8d\n",a->month,a->spxf,a->fzfy,a->znjy,a->sdfy,a->ylfy,a->cxfy,a->srfy);//输出
delRecord(mon);//函数调用
}
break;//结束
}
free(a);//释放内存空间
}
void input(Infor *newI)//函数定义
{
printf("\n请依次输入数据[说明:中间以空格符隔开]:\n(本月月份 食品消费 房租费用 子女费用 水电费用 医疗费用 储蓄费用 收入费用)\n");//输出
scanf("%d%d%d%d%d%d%d%d",&newI->month,&newI->spxf,&newI->fzfy,&newI->znjy,&newI->sdfy,&newI->ylfy,&newI->cxfy,&newI->srfy);//输出
fflush(stdin);//函数调用
}
void writeinfor(Infor *newI)
{
FILE *fp;//定义指针
fp=fopen(FilePath1,"ab+");//复制
if(fp==NULL)//判断
{
printf("无法创建文件:%s",FilePath1);//输出
exit(0);//函数调用
}
fwrite(newI,sizeof(Infor),1,fp);//这里可以做特别处理可防止存在同一月份有2条以上的记录问题。这里就不写了。
fclose(fp);//函数调用
printf("数据录入成功!\n");//输出
}
void changeFormat(void) //暂时只能操作一行文件有待改进
{
FILE *fp1,*fp2;//定义指针
Infor *a;//定义
a=(Infor *)malloc(sizeof(Infor));//复制
fp1=fopen(FilePath1,"rb+");//复制
if(fp1==NULL)//判断
{
printf("无法找到文件:%s\n",FilePath1);//输出
return ; //返回主函数
}
fp2=fopen(FilePath2,"wt+");
if(fp2==NULL)//判断
{
printf("无法创建文件:%s\n",FilePath2);//输出
return ; //返回主函数
}
fputs(" \n……………………………………个人帐簿管理系统……………………………………\n\n",fp2);//输出
fputs("记录月份 食品消费 房租费用 子女费用 水电费用 医疗费用 储蓄费用 本月收入 \n",fp2);//输出
fputs("----------------------------------------------------------------------- \n",fp2);//输出
printf("\n记录月份 食品消费 房租费用 子女费用 水电费用 医疗费用 储蓄费用 本月收入 \n");//输出
printf("----------------------------------------------------------------------- \n");//输出
rewind(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->spxf,a->fzfy,a->znjy,a->sdfy,a->ylfy,a->cxfy,a->srfy);//输出
fprintf(fp2,"%7d %8d %8d %8d %8d %8d %8d %8d\n",a->month,a->spxf,a->fzfy,a->znjy,a->sdfy,a->ylfy,a->cxfy,a->srfy);//输出
fread(a,sizeof(Infor),1,fp1);//函数调用
}
fputs("----------------------------------------------------------------------- \n",fp2);//输出
fputs("关闭本程序继续原程序!\n",fp2);
fclose(fp1);//关闭
fclose(fp2);//关闭
system(FilePath2); //调用打开转换的文本文件
remove(FilePath2);//删除文本文件文件
}
Status search(Infor *a)
{
FILE *fp1;//定义
int mon;//定义整型
int isfound=0; //定义整型
printf("请正确输入要操作的月份:");//输出
scanf("%d",&mon);//输入
fflush(stdin); //清除缓冲区
fp1=fopen(FilePath1,"rb+");//复制
if(fp1==NULL)//判断
{
printf("无法找到文件:%s\n",FilePath1);//输出
return Error; //返回主函数
}
rewind(fp1); //函数调用
fread(a,sizeof(Infor),1,fp1); //函数调用
while(!feof(fp1))//查询操作
{
if(a->month==mon)//判断
{
isfound=1;//找到返回1
break;//结束
}
else
{
isfound=0; // 没找到返回0
}
fread(a,sizeof(Infor),1,fp1);//调用函数
}
fclose(fp1);//关闭
if(isfound)//判断
return OK;//返回主函数
else
return NotFound;//返回主函数
}
void paixu(Infor *a)//排序函数
{
int i=0,j=0,flag=0,t;//定义整型
pType px[8]={{0,0}};//复制
char str[8][10]={"记录月份","食品消费","房租费用","子女费用","水电费用","医疗费用","储蓄费用","本月收入"};//输出
for(;i<8;i++) //判断条件
px[i].no=i; //判断
px[0].data=a->month;//复制
px[1].data=a->spxf;//复制
px[2].data=a->fzfy;//复制
px[3].data=a->znjy;//复制
px[4].data=a->sdfy;//复制
px[5].data=a->ylfy;//复制
px[6].data=a->cxfy;//复制
px[7].data=a->srfy;//复制
for(i=1;i<8;i++)//冒泡排序
{
flag=0;//复制
for(j=0;j<8-i;j++)//for循环
if(px[j].data>px[j+1].data)//判断
{
t=px[j].data;//复制
px[j].data=px[j+1].data;//复制
px[j+1].data=t;//复制
t=px[j].no;//复制
px[j].no=px[j+1].no;//复制
px[j+1].no=t;//复制
flag=1;//复制
}
//输出结果
if(flag==0) break;//结束
}
printf("\n");//输出
for(i=0;i<8;i++)//for循环
{
printf(" %s",str[px[i].no]);//输出
}
printf("\n----------------------------------------------------------------------- \n");//输出
for(i=0;i<8;i++)//for循环
{
printf("%8d ",px[i].data);//输出
}
printf("\n");//输出
}
void modify(Infor *a,int mon)//修改数据
{
FILE *fp1,*fp2;//定义指针
Infor *b;//定义指针
b=(Infor *)malloc(sizeof(Infor));//复制
fp1=fopen(FilePath1,"rt");//复制
fp2=fopen("temp.dat","wt+");//复制
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(FilePath1); //删除源文件
rename("temp.dat",FilePath1);//重命名中间文件
printf("修改数据成功!\n" );
changeFormat(); //显示数据
}
void delRecord(int mon) //删除数据
{
FILE *fp1,*fp2;//定义指针
Infor *b;//定义指针
b=(Infor *)malloc(sizeof(Infor));//复制
fp1=fopen(FilePath1,"rt");//复制
fp2=fopen("temp.dat","wt+");//复制
rewind(fp1);//函数调用
fread(b,sizeof(Infor),1,fp1); //函数调用
while (!feof(fp1)) //重写数据
{
if(b->month!=mon) //判断,选择
fwrite(b,sizeof(Infor),1,fp2); ////函数调用
fread(b,sizeof(Infor),1,fp1);// //函数调用
}
fclose(fp1);//关闭
fclose(fp2);//关闭
remove(FilePath1); //删除源文件
rename("temp.dat",FilePath1);//重命名中间文件
printf("删除数据成功!\n" );//输出
changeFormat(); //显示数据
}
附录资料:不需要的可以自行删除
Abstract: Based on the comprehensive analysis on the plastic part’s structure service requirement, mounding quality and mould menu factoring cost. A corresponding injection mould of internal side core pulling was designed. By adopting the multi-direction and multi-combination core-pulling. A corresponding injection mould of internal side core pulling was designed, the working process of the mould was introduced
C语言详解 - 枚举类型
注:以下全部代码的执行环境为VC++ 6.0
在程序中,可能需要为某些整数定义一个别名,我们可以利用预处理指令#define来完成这项工作,您的代码可能是:
#define MON 1
#define TUE 2
#define WED 3
#define THU 4
#define FRI 5
#define SAT 6
#define SUN 7
在此,我们定义一种新的数据类型,希望它能完成同样的工作。这种新的数据类型叫枚举型。
1. 定义一种新的数据类型 - 枚举型
以下代码定义了这种新的数据类型 - 枚举型
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
(1) 枚举型是一个集合,集合中的元素(枚举成员)是一些命名的整型常量,元素之间用逗号,隔开。
(2) DAY是一个标识符,可以看成这个集合的名字,是一个可选项,即是可有可无的项。
(3) 第一个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加1。
(4) 可以人为设定枚举成员的值,从而自定义某个范围内的整数。
(5) 枚举型是预处理指令#define的替代。
(6) 类型定义以分号;结束。
2. 使用枚举类型对变量进行声明
新的数据类型定义完成后,它就可以使用了。我们已经见过最基本的数据类型,如:整型int, 单精度浮点型float, 双精度浮点型double, 字符型char, 短整型short等等。用这些基本数据类型声明变量通常是这样:
char a; //变量a的类型均为字符型char
char letter;
int x,
y,
z; //变量x,y和z的类型均为整型int
int number;
double m, n;
double result; //变量result的类型为双精度浮点型double
既然枚举也是一种数据类型,那么它和基本数据类型一样也可以对变量进行声明。
方法一:枚举类型的定义和变量的声明分开
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY yesterday;
enum DAY today;
enum DAY tomorrow; //变量tomorrow的类型为枚举型enum DAY
enum DAY good_day
展开阅读全文