- 需求分析:
- 设计题目:
宿舍财务管理系统
2.系统功能需求分析:
随着宿舍生活的丰富度提高,宿舍之间或宿舍内的集体活动也就越来越多,因此宿舍支出次数的量也不断增多。因此,在大数据时代背景下,我们尝试用更为方便的电子系统来记录生活的支出。
系统功能包括——能注册宿舍信息及宿舍用户信息;能删除宿舍及宿舍成员信息;能修改成员信息;能通过密保找回用户私密信息;能够查询用户一天,一月,一学期,一学年收支信息。
- 概要设计:
- 详细设计:
该设计是一个豪华版的宿舍财务管理系统,该系统中的主要数据包括宿舍信息、宿舍成员姓名、宿舍成员费用支出信息和每个宿舍的成员总数,这些数据的类型尽管不同,但他们之间是有内在联系的,都属于宿舍财务管理系统信息的内容,所以在本程序中将他们组合成一个组合数据,也就是结构体。用户信息数据表、用户支出信息表分别保存在一个文件中,所有的用户信息和用户费用支出一共构成两张表,在程序设计时使用结构体链表存储这些数据,每当输入信息完成,可以将这些数据保存在磁盘文件中。
- 调试分析过程描述:
用户支出信息调试:
在此大模块的程序调试中,经常遇到现实和理想是有差距的。在文件数据特别是在讲文件读入链表后对链表的操作,有出现了系统崩溃和结构不相符的现象。经过自己的仔细琢磨,发现原来自已定义的指针有些忘记初始化,并且忘记对链表的第一个表头的数据进行特别的处理,以致在没有数据或只有链表表头有数据时,系统逻辑出现了错误,所以导致了运行的错误。另外,在调试的过程中还有一个毛病经常犯的就是在输入的操作中因为是对结构体成员进行操作,所以有时会忘记加入取地址符号,以至于在输入信息的时候发生内存错误所以程序运行崩溃。
程序界面包装调试:
程序外包是属于一个比较大的工作,因此往往会出现一些小细节的问题。例如:在外包中,上一行与下一行的位置不相称、或者上一行在屏幕显示的时候总是差几个空格,并且程序进行到那里是需要好几个步骤的,因此程序界面的调试是比较耗费时间与精力的。为了解决这个问题,我所选择方法是先统一利用调试好的包装代码,然后在代码中进行对其它部分包装,最后完成一个大模块后再进行测试,这样效率真的提高的许多。
用户管理操作调试:
1、内存泄漏
虽然一开始程序设计的逻辑关系弄的非常的清晰,但是那都是宏观的模块,当我们需要写成一个个小模块来实现大模块的功能时,一些细节性的错漏会引发非常的问题。有时候,那个问题不会马上显示,但是会慢慢呈现出来。例如,内存泄漏。虽然我把创建和释放链表的功能都模块化成一个子函数,但是在我写释放链表函数的时候,又一次犯了释放顺序的低级错误,导致看似已经释放,实际并没有,因为释放节点的命令只在首节点有效。
2、结构体信息输入错误
虽然USER结构体里封装了用户的属性,按道理说一般是不会出错的,但是就是因为这样的心理,导致我错看密保问题和密保答案的变量,错换了两个变量的位置。于是乎,这个问题在找回密码中显示了出来,如果之前没有仔细验证的话,很容易遗漏这个Bug。
- 测试结果:
第一个操作页面功能菜单:
1.用户注册:用户需要注册新用户才能有进一步的使用功能,每个宿舍第一个注册的为宿舍长
2.用户删除:用户可以对自己的账号进行注销
3.用户查询:查询已注册的用户宿舍号,用户名等信息
4.用户登录:用户进行登录后,将进入下一个功能界面
5.修改密码:用户可以自行的修改自己的密码
6.找回密码:用户如果忘记密码,则可通过密保问题,查询到自己的用户密码
7. 关于程序:介绍该程序的简单情况
8. 退出程序
第二个信息管理操作页面功能菜单:
1.本月宿舍支出查询:用户可查询本宿舍的本月的支出总金额和本月费用平摊金额
2.本月个人支出查询:用户可查询本月宿舍成员每个人的支出情况
3.宿舍历史支出查询:用户可查询宿舍历史支出的情况
4. 个人历史支出查询:用户可查询个人历史支出的情况
5. 录入新的支出信息:只有管理员可以增加本宿舍成员的支出信息
6.修改已有支出信息:只有管理员可以修改已存在的宿舍支出信息
7.删除已有支出信息:只有管理员可以删除已存的支出信息
8.更新已有支出信息:用户可以更新支出信息(即自动删除1年前的支出信息)
9.用户登录注销
10.退出程序
程序源码
#ifndef__STATEMENT_H__
#define__STATEMENT_H__
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
#include<math.h>
#include<mmsystem.h>
#define BYTE unsigned char
#define DWORD unsigned long
#define LENGTH 20
typedef struct ID //用来存放数据在文件中的位置
{
DWORD IdNumber;
struct ID*pNext;
}ID;
typedef struct TIME
{
DWORD year,
DWORD month;
DWORD day:
}TIME;
typedef struct SPENDING //支出结构体
{
char ObjName[LENGTH]; //支出对象名
TIME time; //时间
char place[LENGTH]: //地点
char reason[LENGTH]; //原因
char Pay Way[LENGTH]; //交易方式
float money; //金额
struct SPENDING*pNext; //自类型指针
}SPENDING;
typedef struct USER //用户结构体
{
char Username[ LENGTH]; //用户名
har Userkey [LENGTH]; //用户密码
char Userquc[ LENGTH]; //用户密保
char Userans[LENGTH]; //密保答案
char dormitory[LENGTH]; //宿含名
}USER;
typedef struct DORMITORY //宿舍结构体
har dormitory[ LENGTH; //宿舍名
DWORD nmembers; //成员数
USER* members; //宿舍成员
struct DORMITORY*pNext;
}DORMITORY;
/*****************************************************************/
/**体界面函数**/
void Initate();
USER UserStartPage();
void MessagesTartPage(USER curUser);
/*****************************************************************/
/**用户操作函数**/
USER Login(); //用户登录
void Enroll(); //用户注册
void DeleteUer(); //删除用户
void ListUer(); //用户查询
void ChangeKy(); //修改密码
void FindKey(); //找回密码
void AboutFmdmMS(); //关于宿舍财务管理系统( the financial management system of dormitories)
/*****************************************************************/
/**信息操作函数**/
void DorSendinfoMUSER curser);//本月宿舍支出查询
void DorspendinfH(USER curser);//宿舍支出历史记录查询
void Perspendinfo(USER curser);//本月个人支出查询
ID* Perspendinfoh(USER curser);//个人支出历史记录查询
void Write Newspendinfo( USER curser);//新支出
void Changespendinfo( USER curser;//修改支出信息
void Deletespendinfo( USER curser);//删除支出信息
void Updataspendhistory( USER curser);//更新支出历史记录
/*****************************************************************/
#include "statement.h"
USER Login()//用户登录
{
system("title用户登录");
system("cls");
printf("\t\t\t***欢迎使用宿舍管理系统***\n");
printf("t\t\t\t <用户登录>\n");
/*************************************************************/
/**用户登录输入**/
USER curUser;
printf("\n请输入您的宿舍号:");
scanf("%19s",curUser.UserName);
whild(getchar()!='\n');
printf("\n请输入您的用户密码:");
scanf("%19s",curUser.UserKey);
whild(getchar()!='\n');
/**************************************************************/
/**用户匹配**/
DORMITORY head;
head. members=NULL;
head. pNext=NULL;
readUser(&head); //输入用户信息
if(head. pNext==NULL)
{
printf("\n不存在此用户!\n请检查您输入的信息是否有误!请重新输入!!\n");
strcpy(curser dormitory, "NoSuchUser\n")
printf("n请按任意键继续!\n");
getchar();
return curUser;
}
DORMITORY* pTail=head. pNext;
BYTE flag=0;//标识密码是否匹配成功
while(pail! =NULL && !flag)
{
if(strcmp(pTail->dormitory,curUser.dormitory)==0)//匹配宿舍
{
for (DWORD i=0; i<pTail->nMember && !flag; i++)
{
if (strcmp(pTail->member[i].UserName,curUser.UserName)==0)//匹配用户
{
if (strcmp(pTail->member[i].UserKey,curUser.UserKey)==0)//匹配密码
{
strcpy(curUser.UserQue,pTail->members[i].UserQue);
strcpy(curUser.UserQue,pTail->members[i].UserQue);
}
else
{
printf("\n密码错误!\n");
strcpy(curUser.dormitory,"NoSuchUser\0");
Sleep(200);
}
flag=1;
}
}
}
pTail=pTail->pNext;
}
if (!flag)
{
printf("\n不存在此用户!\n请检查您输入的信息是否有误!请重新输入!!\n");
releasedorlist (&head);
memset(&curser, 0, sizeof(curser));
strcpy(curser dormitory, Nosuchuser\0);
printf(n请按任意键继续!n");
getchar();
return curser;
}
releasedorlist(&head);//释放宿舍链表
return curser;
}
void Enroll()//用户注册
{
system(" title用户注册");
system("cls");
printf("\t\t\t ***欢迎使用宿舍财务管理系统***\n");
printf("\t\t\t\t<用户注册>\n");
/**************************************************************************/
/**新用户信息输入**/
USER curser;
memset(&curser, 0, sizeof(curser));
userinfolnput(& curser);//用户信息输入
/*****************************************************************************/
/**用户信息录入**/
DORMITORY head;/宿舍链表头节点
head. members =NULL;
head. pnext NULL;
readuser(&head);//读取所有用户信息
DORMITORY* pail;
BYTE flag=0;//添加用户是否成功的标志
for( pail=head. pnext: pail!l=NULL; pail= pail-> pnext)//如果已存在该宿舍,则在该宿舍下添加该用户
{
if( strcmp( curser. dormitory, pail-> dormitory)=0)/匹配宿含
{
Tail->members=
(USER* )realloc(ptail->members, sizeof(USER)*(ptail->nmembers+1));//用户信息赋值
usercopyto(&(ptail->members [ptaii->nmembers]),&curuser);
ptaii->members++
flag=1
}
}
if(!flag)//如果该宿舍尚未存在,则创建新宿舍
{
printf("宿舍注册成功!\n");
pail=&head;
while( pail-> pnext!=NULL)//指向尾节点
pail=ptail->pnext;
DORMTTORY*pNew=NULL;//创建宿舍新节点
pnew =(DORMITORY*)malloc(sizeof(DORMITORY));
if(pnew==NULL)
{
printf("\n宿舍注册失败!\n");
releasedorlist(&head);//释放宿舍链表
Sleep(100);
return;
}/*
memset(pnew->dormitory, 0, sizeof(char)*LENGTHD);
pnew->nmembers=0;
pnew->members=NULL;
PNEW->pnext=NULL: */
memset(pnew, 0, sizeof(DORMITORY) );
strcpy(pNew-> dormitory, curser. dormitory);//复制宿舍名
pNew-> members=(USER*) malloc( sizeof(USER));//创建用户新节点
if(pnew==NULL)
{
printf(("\n注册失败!\n");
releasedorlist(&head);//释放宿舍链表
Sleep(100);
return;
}
pnew->nmembers= 1;//用户信息赋值
usercopyto(pnew->members, &curser);
ptail->pnext=pnew;
}
writelser(&head);//写入用户信息
releasedorlist(&head);//释放链表
printf("\n用户注册成功!\n")
Sleep(200)
}
void Deletelser()//删除用户
{
system(" title别除用户");
system("cls");
printf("t\t\t***欢迎使用宿舍财务管理系统***\n");
printf("t\t\t\t <用户删除>\n");
/***********************************************************/
/**本删除用户输入**/
char Dorname [LENGTH
Username [LENGTH
Rootkey [LENGTH
printf("n请输入要操作的宿舍名:")
scanf(%19s", Dorname)
while(getchar! =\n)
printf("\n请输入要删除的用户名:");
scanf("19s", Username);
while(getchar!()! ='\n');
printf("\n请输入舍长的用户密码:");
scanf("%19s", Rootkey);
while(getchar()!='\n');