c 课程设计个人财政支出管理南京理工大学谢记超.docx
《c 课程设计个人财政支出管理南京理工大学谢记超.docx》由会员分享,可在线阅读,更多相关《c 课程设计个人财政支出管理南京理工大学谢记超.docx(25页珍藏版)》请在冰豆网上搜索。
c课程设计个人财政支出管理南京理工大学谢记超
南京理工大学
C++课程设计报告
姓名:
***
一、课程设计题目:
个人财政支出管理(A级)
程序功能简介:
将个人财物的目标及当前存款、支出保存下来,可随时更新查看,比较盈余与目标的差距。
设计要求:
(1)将收支的数据与相应的函数封装到类中,并改写主程序,使程序结构化。
(2)增加保存每笔收支的记录,并对每笔记录增加日期录入,按日期顺序保存查看记录。
将所有记录放入一个文件中,每次运行程序时首先打开这个文件,程序运行完毕时将更新的记录放回文件中。
(3)完善程序,补充类中数据成员(dlbalance)的计算和输出,要求每笔收入和支出都要重新统计当前情况下的盈余数目。
(4)增加程序监控功能,当输入时间发生错误(如月份超过十二),要求重新输入正确的时间;当结余数目为负数时,输出信息,警告已超支。
二、对题目的分析,以及功能的实现
关键的四个类
1.classCFince数据类2.classCNode结点类3.classCList链表类4.classCRecord处理类两个函数
1.判断日期是否正确的函数2.main()函数实现如下功能
1.程序的结构化,将各函数封装到类中。
2.数据的保存与读取。
3.数据的处理,用相应函数实现
4.优化处理,界面美观,人性化提示,数据输入的监控
三、程序设计过程中遇到的问题与解决方法
1.开始做出的程序添加收入与支出记录是未进行日期检查,导致不实际的日期也被录入。
对于日期的检查用了函数IsDateRight来实现,其中应用了if语句,switch语句帮助实现该功能。
2.数据的保存与读取开始实现不了,保存下来的数据格式不正确,打不开,再次运行时上次的数据也未能读取。
最终在classCRecord处理类中添加voidReadFromFile()和voidSaveToFile()实现了这个功能,里面用到了输入输出流ifstream和ofstream,实现数据的保存与再次读取是很高兴的,最令人兴奋的是关闭程序后可以在文本文件中看到收支记录!
3.数据类结点类链表类数据处理类的编写是很复杂的,环环相扣,数据类、节点类是基础,链表类将数据串起来,然后再用数据处理类中的函数处理链表中的数据!
这四大类真是让人费劲心思!
当时实现这个生产链时,那是相当有成就感的!
4.如何区分开收入与支出记录输出,当时困扰了我很久,实在不希望不能实现收入记录与支出记录的分开显示,后来发觉可以通过判断函数的值来判断该笔记录是收入还是支出,最终实现了查看收入记录则只显示收入记录,查看支出记录只显示支出记录。
5.累计计算余额,实现超支预警,
voidCRecord:
:
ViewBalance()
{
list.ShowList();
if(list.GetLastNode()->GetData()->GetBalance()<0)
{cout<<"您的财政已超支!
"<}累积计算的实现别看代码不长绝非易事。
6.主界面的美化,还是花了不少心思的!
四、程序中尚存在的不足
1.根据日期修改记录只实现了金额的修改,而日期和用途的修改未实现。
2.入日期时用cin>>a>>b>>C;;获取时间,在Dos屏幕中输入201285100而入的的100会被下一次cin>>d;获得(即被当做收入获得)如何在取得相应数据后清空为取得的数据?
cin.ignorecin.synccin.ignore都不行。
3.入与支出的用途在Dos屏幕中只能输入英文,不能输入汉语,如果这个程序用
MFC编程来编写效果会更好!
4.操作未实现,有时候运行次数过多就会在评上留下很多东西,DOS屏幕会显乱。
五、程序演示截图
#include#include#include#include
boolIsDateRight(int,int,int);//函数原形说明
staticdoubledlPurpose=0.0;//全局静态变量,目标classCFinance//数据类
{
intnYear,nMonth,nDay;doubledlIncome,dlOutput;doubledlBalance;
charszPurpose[20];doubledlGap;
public:
CFinance();//缺省构造函数
CFinance(int,int,int);//为日期赋值的构造函数intCompare(CFinance&);//比较日期大小的函数
voidShow();//展示该笔收支情况,包括盈余状
况
voidSetFinance(int,int,int,double,double,char*);
//为所有成员变量赋初值的函数
voidCalculate(doubledlBal);//累计计算总收入的函数doubleGetBalance();
voidModifyData();//修改数据的函数
voidSetVal(int&,int&,int&,double&,double&,char*);
//获得各成员值的函数
boolIsDateEqual(int,int,int);////判断日期是否存在
voidShowWithoutBalance();//展示该笔收支情况,不包括盈余情况
};
CFinance:
:
CFinance()//缺省构造函数
{
dlIncome=0.0;dlOutput=0.0;dlBalance=0.0;
}
CFinance:
:
CFinance(intyear,intmonth,intday)//为日期赋值的构造函数
{
nYear=year;nMonth=month;nDay=day;dlIncome=dlOutput=0.0;dlOutput=0.0;dlBalance=0.0;
}
intCFinance:
:
Compare(CFinance&finance)//比较日期的大小(大于取1,小于取-1,相等取0)
{
if(nYear>finance.nYear)return1;
if(nYear{
if(nMonth>finance.nMonth)return1;
if(nMonth{
if(nDay>finance.nDay)return1;
if(nDayif(nDay==finance.nDay)return0;
}
}
}
voidCFinance:
:
Show()//展示该笔收支情况,包括盈余状况
{
cout<<"日期:
"<"<"<"<"<"<}
voidCFinance:
:
SetFinance(intyear,intmonth,intday,doubleincome,doubleoutput,char
*purpose)
{//为所有成员变量赋初值的函数
nYear=year;nMonth=month;nDay=day;dlIncome=income;dlOutput=output;strcpy(szPurpose,purpose);
}
voidCFinance:
:
Calculate(doubledlBal)//累计计算总收入的函数
{
dlBalance=dlBal+dlIncome-dlOutput;
}
doubleCFinance:
:
GetBalance()
{
returndlBalance;
}
voidCFinance:
:
ModifyData()//修改数据函数
{
doubletemp;
if(dlIncome>0)//若dlIncome>0,修改收入数据;否则修改支出数据
{
cout<<"输入修改后的收入:
";cin>>temp;
if(temp>0)
{
}
else
{
}
else
{
}
cout<<"修改成功!
"<
cout<<"输入有误,修改失败!
"<cout<<"输入修改后的支出:
";cin>>temp;
if(temp>0)
{
}
else
{
}
}
}
cout<<"修改成功!
"<
cout<<"输入有误,修改失败!
"<voidCFinance:
:
SetVal(int&year,int&month,int&day,double&income,double&output,char*purpose)
{//获得各成员值的函数
year=nYear;month=nMonth;day=nDay;income=dlIncome;output=dlOutput;strcpy(purpose,szPurpose);
}
boolCFinance:
:
IsDateEqual(intyear,intmonth,intday)//判断日期是否存在
{
if(nYear==year&&nMonth==month&&nDay==day)
{
}
else
{
}
}
returntrue;
returnfalse;
voidCFinance:
:
ShowWithoutBalance()//展示该笔收支情况,不包括盈余情况
{
cout<<"日期:
"<"<"<"<}
classCNode//结点类
{
CFinance*pData;//用于指向数据的指针,相当于节点中存放数据的部分
CNode*pNext;//用于指向下一节点的指针public:
CNode();//默认构造函数
CNode(CNode&node);//拷贝构造函数
voidInputData(CFinance*pdata);//将数据的地址赋值给数据指针pData的函
数
voidShowNode();//输出本节点所指向的数据
CFinance*GetData();//获得该节点所指向的数据的地址friendclassCList;//把CList定义为友员函数
};
CNode:
:
CNode()//默认构造函数
{
pData=0;pNext=0;
}
CNode:
:
CNode(CNode&node)//拷贝构造函数
{
pData=node.pData;pNext=node.pNext;
}
voidCNode:
:
InputData(CFinance*pdata)//将数据的地址赋值给数据指针pData的函数
{
pData=pdata;pNext=0;
}
voidCNode:
:
ShowNode()//输出本节点所指向的数据
{
pData->Show();
}
CFinance*CNode:
:
GetData()//获得该节点所指向的数据的地址
{
returnpData;
}
classCList//链表类
{
protected:
CNode*pHead;//定义一个CNode的头指针
public:
CList();//构造函数
~CList();//析构函数
voidAddNode(CNode*pnode);//增加结点
voidDeleteNode(CNode*);//删除制定结点
CNode*LookUp(CFinance&);//根据日期查找指定数据,并返回该数据所在结点指针
voidShowList();//输出链表中的数据
voidDeleteList();//删除链表中的数据CNode*GetListHead();//获得链表头指针
CNode*GetListNextNode(CNode*);//返回指定结点的下一结点指针voidInsert(CNode*);//据日期升序插入结点
CNode*GetLastNode();//返回尾部的头指针
voidCalBalance();//逐个结点计算盈余
};
CList:
:
CList()//构造函数
{
pHead=0;
}
CList:
:
~CList()//析构函数
{
DeleteList();
}
voidCList:
:
AddNode(CNode*pnode)//增加结点
{
if(pHead==0)//头指针为空
{
pHead=pnode;
}
else
{
}
}
pHead->pNext=0;
GetLastNode()->pNext=pnode;pnode->pNext=0;
voidCList:
:
DeleteNode(CNode*pnode)//删除制定结点
{
if(!
pHead)//头指针为空,即还未建立链表
{
cout<<"删除结点错误:
链表不存在!
"<(1);
}
if(pnode==pHead&&pHead->pNext==0)//只有一个节点时删除节点
{
deletepHead->pData;deletepHead;pHead=0;
}
elseif(pnode==pHead)//链表中有多个结点,要删除的结点是头结点
{
CNode*p=pnode->pNext;deletepHead->pData;deletepHead;
pHead=p;
}
else//链表中有多个结点,要删除的结点是其他节点
{
CNode*p=pHead;while(p&&p->pNext!
=pnode)
{
p=p->pNext;
}
if(!
p)
{
}
else
{
cout<<"删除结点错误:
结点不存在!
";exit
(1);
CNode*q=pnode->pNext;deletepnode->pData;
deletepnode;p->pNext=q;
}
}
}
CNode*CList:
:
LookUp(CFinance&finance)//根据日期查找指定数据,并返回该数据所在结点指针
{
if(pHead==0)return0;CNode*pn=pHead;while(pn)
{
if(pn->pData->Compare(finance)==0)returnpn;pn=pn->pNext;
}
return0;
}
voidCList:
:
ShowList()//输出链表中的数据
{
if(!
pHead)
{
cout<<"链表为空"<}
CNode*p=pHead;while(p)
{
p->ShowNode();p=p->pNext;
}
}
voidCList:
:
DeleteList()//删除链表中的数据
{
if(pHead==0)return;CNode*p,*q;p=pHead;
while(p)
{
deletep->pData;q=p;
p=p->pNext;deleteq;
}
pHead=0;
}
CNode*CList:
:
GetListHead()//获得链表头指针
{
returnpHead;
}
CNode*CList:
:
GetListNextNode(CNode*pnode)//9
{
returnpnode->pNext;
}
voidCList:
:
Insert(CNode*pnode)//按日期的升序插入结点
{
CNode*p,*q;if(pHead==0)
{
pHead=pnode;pHead->pNext=0;return;
}
if(pHead->pData->Compare(*(pnode->pData))==1)
{
pnode->pNext=pHead;pHead=pnode;
return;
}
p=pHead;
while(p&&p->pData->Compare(*(pnode->pData))==-1)
{
q=p;
p=p->pNext;
}
q->pNext=pnode;pnode->pNext=p;
}
CNode*CList:
:
GetLastNode()//返回尾部结点的指针(该程序未用到,用于扩展功能)
{
if(!
pHead)
{
return0;
}
CNode*p=pHead;while(p->pNext)
{
p=p->pNext;
}
returnp;
}
voidCList:
:
CalBalance()//逐个结点计算盈余
{
if(!
pHead)return;doubletemp=0;CNode*p=pHead;while(p)
{
p->pData->Calculate(temp);temp=p->pData->GetBalance();p=p->pNext;
}
}
classCRecord//处理记录类
{
CListlist;//把CList的对象list作为CRecord的子对象
public:
voidReadFromFile();//从文本文档读取数据
voidSaveToFile();//把数据写进文本文档
voidInputIncomeRecord();//增加收入数据
voidInputOutputRecord();//增加支出数据
voidViewIncomeRecord();//展示全部收入记录
voidViewOutputRecord();//展示全部支出记录
voidViewBalance();//展示全部收入与支出记录,显示盈余情况,实现超支预警
voidLookUpRecord();//根据日期寻找记录
voidEditRecord();//根据日期修改记录
voidDeleteRecord();//根据日期删除记录
voidsetgoal(double);//设置存储目标
};
voidCRecord:
:
setgoal(doublegoal)//设置存储目标
{dlPurpose=goal;}
voidCRecord:
:
ReadFromFile()//从文本文档读取数据
{ifstreaminfile1("目标dlPurpose.txt");if(!
infile1)
{
cout<<"文件读取失败!
"<exit
(1);
}
infile1>>dlPurpose;
ifstreaminfile("收支记录finance.txt");if(!
infile)
{
cout<<"文件读取失败!
"<(1);
}
intyear,month,day;doubleincome,output;charpurpose[20];
while(infile>>year>>month>>day>>income>>output>>purpose)
{
CFinance*pfinance=newCFinance;
pfinance->SetFinance(year,month,day,income,output,purpose);CNode*pnode=newCNode;
pnode->InputData(pfinance);list.AddNode(pnode);
}
list.CalBalance();
}
voidCRecord:
:
SaveToFile()//把数据写进文本文档
{ofstreamoutfile1("目标dlPurpose.txt");if(!
outfile1)
{
cout<<"文件写入失败!
"<(1);
}
outfile1<ofstreamoutfile("收支记录finance.txt");if(!
outfile)
{
cout<<"文件写入失败!
"<(1);
}
intyear,month,day;doubleincome,output;charpurpose[20];
CNode*p=list.GetListHead();while(p)
{
p->GetData()->SetVal(year,month,day,income,output,purpose);
outfile<p=list.GetListNextNode(p);
}
}
voidCRecord:
:
InputIncomeRecord()//增加收入数据
{
intyear,month,day;doubleincome;charpurpose[20];
cout<<"请输入日期:
(例如:
2012229)";cin>>year>>month>>day;while(!
IsDateRight(year,month,day))
{
cout<<"日期不正确!
请重新输入:
(例如:
2012229)";cin>>year>>month>>day;
}
cout<<"请输入收入金额:
";cin>>income;
cout<<"请输入来源:
";cin>>purpose;
CFinance*pfinance=newCFinance;
pfinance->SetFinance(year,month,day,income,0,purpose);CNode*pnode=newCNode;
pnode->InputData(pfinance);list.Insert