客户消费积分管理系统-课程设计报告书.doc
.客户消费积分管理系统的设计与实现客户消费积分管理系统摘 要:客户消费积分管理系统开发的总体目标是实现酒吧会员卡的积分和打折管理。主要是通过对客户积分卡积分的统计,再通过不同层段的积分有不同的折扣。本系统根据客户及商品的数据需求,采用了线性表的链式存储结构,主要功能包括数据的录入、插入、删除、修改、以及数据的显示,对客户积分的管理,对客户购物时依据积分的数目进行不同打折处理。 关键词:C+语言;客户积分管理系统;数据结构;链式存储结构;1前言 当今世界由于人类文明进入了高速发展阶段,计算机技术已经取得了长足的发展,计算机已经普及到各大商城和小市场的管理当中,介于此,经过了网上的 资料查阅和数据分析,开发了这个客户消费积分管理系统,对一些商品进行折扣的统计和管理。设计一个程序用于管理客户的消费情况,从而根据客户的消费积分对客户实行不同程度的打折优惠。对于客户消费积分管理系统利用线性表的链表存储方式,使用结构体指针将每一个用户联系起来。程序中设计了添加用户查找用户修改用户删除用户统计客户数量的功能,充分满足对于管理系统的要求。2设计分析根据题目要求及本次课程设计的目的,采用结构体来存储每组数据,用单链表对每组数据进行相应的操作。现把相应的设计思路及各个函数解析如下。2.1数据结构设计分析2.1.1 存储客户信息的结构体客户资料有、号、客户编号、消费金额、客户积分等信息。具体结构如下:struct Client/客户信息string CCardNumber;/客户编号stringCNumber;/客户号float CBuy;/客户消费金额float CGrade;/客户积分string CName;/客户名称;2.1.2 存储商品信息的结构体 首先用一个商品信息的结构体Production存储商品的价格、商品的固定积分、商品的名称,在用一个数组进行存储每一件商品,使用数组和for循环能够便捷并容易的进行数据的操作。另外再用一个商品消费的记录ProCli,用来记录每个客户消费商品的记录具体结构如下:structProduction/商品信息float PPrice;/商品价格int PGrade;/商品积分string PName;/商品名称;struct PN/产品消费的信息记录string ProName16;/记录消费了的产品的名称int mount16;/记录该产品的消费数量;struct ProClistring Cardnum;/客户的名称PN CPN;/消费产品和数量2.2各个函数分析2.2.1 主函数函数原型:int main()main()函数主要是整个系统的控制端,主要功能是控制整个程序的运行。从主函数开始调用各相关函数来达到相应的功能。由于有多个不同的选项,所以用一个switch()语句控制每个函数调用,控制起来方便、明了。关键代码如下:switch(work)case 1:cout<<"继续请输入1,返回请输入2"<<endl;cin>>work;if(work=1)cout<<"请输入要查询客户的名称或编号或号: "cin>>str;locateElem_L(client,str);else if(work=2)system("cls");face(); elsecout<<"输入错误!"<<endl;system("cls");face(); break;case 2:cout<<"删除请输入1,增加请输入2,返回请输入3: "cin>>work;if(work=1)deleteElem_L(client,procli);else if(work=2)cout<<"请输入客户编号"<<endl;cin>>clients.CCardNumber;cout<<"请输入客户号"<<endl;cin>>clients.CNumber;cout<<"请输入客户名称"<<endl;cin>>clients.CName;cout<<"请输入客户消费金额"<<endl;cin>>clients.CBuy;cout<<"请输入客户积分"<<endl;cin>>clients.CGrade;insertElem_L(client,procli,clients);else if(work=3)system("cls");face(); elsecout<<"输入错误!"<<endl;system("cls");face(); break;case 3:cout<<"现在进行客户信息修改:继续请输入1,返回请输入2"<<endl;cin>>work;if(work=1) cout<<"请输入要修改的客户的名称或编号或号: " cin>>str; recompose(client,str);else if(work=2)system("cls");face(); elsecout<<"输入错误!"<<endl;system("cls");face(); break;case 4:trverseLnode(client);break;case 5:purchase(client,procli);break;case 6:cout<<"继续请输入1,返回请输入2"<<endl;cin>>work;if(work=1)cout<<"查询的客户消费资料,请输入客户名称:"cin>>str;locateElem_P(procli,str);else if(work=2)system("cls");face(); elsecout<<"输入错误!"<<endl;system("cls");face(); break;case 7:system("cls");face(); break;case 8:cout<<"是否确定退出,是,请输入'yes',否,请输入'no'!: "cin>>str;if(str="yes")cout<<"是否确定保存,是,请输入'yes',否,请输入'no'!: "cin>>str1;if(str1="yes")printer(client);printer(procli);cout<<"已经保存成功"<<endl;cout<<"已成功退出!"<<endl;return 0;else if(str ="no")break;2.2.2 读文件函数函数原型:无 把存储在文件中的客户信息、产品信息及产品消费信息读入到链表中去,为各操作做准备,也就相当于打开系统时,加载数据一样。在读文件中时,主要用到C+里的文件流操作,从文件(客户信息)client.txt和(客户消费信息保存文件)clientproduction.txt两个文件中读取信息,分别存放到链表client和procli中。client.txt文件是每一行存放一个客户的信息,是按客户编号、客户号、客户名称、客户消费金额、客户积分存放的。而clientproduction.txt文件是客户、产品名称、产品的消费数量的顺序存储的。在读取客户信息时,判断客户编号和客户省份证号是否为“NULL”来确定客户是否全部读完。代码如下:initList_L(client);clientp = client;ifstream enter;enter.open("client.txt",ios:in);dohi = new LNode;hi->next = clientp->next;enter>>hi->data.CCardNumber;enter>>hi->data.CNumber;enter>>hi->data.CBuy;enter>>hi->data.CGrade;enter>>hi->data.CName;clientp->next = hi;clientp = clientp->next;/cout<<clientp->data.CCardNumber<<" "<<clientp->data.CNumber<<" "<<clientp->data.CName<<endl;while(clientp->data.CCardNumber!="NULL")&&(clientp->data.CNumber!="NULL");2.2.3 菜单函数函数原型:void face()在主函数调用此函数,展示整个系统可供用户选择的功能选项,清晰明了,使用户对系统的操作更容易掌握。显示各个选项,把后台功能显示在显示器上,给用户以提醒。2.2.4 显示函数函数原型:void trverseLnode(LinkList L)此函数用来显示所有客户的信息,包括、号、客户编号、消费金额、客户积分等信息,当客户想查看所有客户信息时,可以使用此功能。不过说白了,也就是把链表中的东西打印出来。代码如下:void trverseLnode(LinkList L) /遍历链表Lnode *p;cout<<"客户编号 "<<"号 "<<"客户名称 "<<"消费金额 "<<"客户积分"<<endl;for(p=L->next; p!=NULL; p=p->next)if(p->data.CCardNumber!="NULL")cout<<p->data.CCardNumber<<" "<<p->data.CNumber<<" "<<p->data.CName" <<" "<<p->data.CBuy<<" "<<p->data.CGrade<<endl;cout<<endl;2.2.5 查询函数函数原型:bool locateElem_L(LinkList L,string e)bool locateElem_P(LinkListP L,string e)查询函数设计了两个,进行两种功能的查询,一是查询客户信息,包括、号、客户编号、消费金额、客户积分等信息,二是查询客户消费信息记录,用户可以看到客户的消费情况作出商业上的调整,选择相应的查询功能,系统会给出不同的信息提示,要求用户输入一些相应的信息,比如客户等,为实现这两种不同的查询功能,编写了以下查询函数。(1) 客户信息查询: bool locateElem_L(LinkList L,string e)/按值查找 LNode *p = L->next;while(p)if(p->data.CCardNumber=e)break;else if(p->data.CNumber=e)break;else if(p->data.CName=e)break;p = p->next;if(p)cout<<"客户编号 "<<"号 "<<"客户名称 "<<"消费金额 "<<"客户积分"<<endl;cout<<p->data.CCardNumber<<" "<<p->data.CNumber<<" "<<p->data.CName<<" "<<p->data.CBuy<<" "<<p->data.CGrade<<endl;return true;elsecout<<"不存在此客户!"<<endl;return false;(2) 客户消费情况查询: bool locateElem_P(LinkListP L,string e)/按值查找|遍历查询 int i,j;bool flag = false;LPode *p = L->next;while(p)if(p->data.Cardnum=e)break;p = p->next;if(p)cout<<"客户名称 "<<"产品名称 "<<"消费数量 "<<endl;if(p->data.CPN.mount0<0)flag = true;for(i=0,j=0; p->data.CPN.mountj>0; i+,j+)cout<<e<<" "<<p->data.CPN.ProNamei<<" "<<" "<<p->data.CPN.mountj<<endl;if(flag)cout<<"无消费记录!"<<endl;return true;elsecout<<"不存在此客户!"<<endl;return false; 2.2.6 购买产品的函数函数原型:void purchase(LinkList L,LinkListP PI)在此函数中,用户只需按照系统所提示的每一步操作,即可完成产品的购买,并且可以对用户输入的信息作出相应的回应。当用户输入的信息在数据库中不存在的时候就会作出反馈,结束用户的操作。购买产品主要先是选择购买商品的功能的序号然后回车,系统会给出请输入客户的,回车后如果没有用户所输入的客户的话,系统则会自动提示用户没有该信息,并结束用户继续完成购买操作。如果存在这个用户的话,就会把该客户的客户信息打印出来,然后提示用户输入购买的产品名称和数量,主要代码是:void purchase(LinkList L,LinkListP PI)LNode *p = L->next;LPode *pi = PI->next;bool flag1 = false,flag2 = false;stringame; /输入的客户名string proname; /输入的产品名int count; /输入的产品数量int i,j;cout<<"请输入客户的: "<<endl;cin>>cname;while(p)if(p->data.CName=cname)flag1 = true;break;p = p->next;while(pi)if(pi->data.Cardnum=cname)flag2 =true;break;pi = pi->next;if(p)cout<<p->data.CCardNumber<<" "<<p->data.CNumber<<" "<<p->data.CName<<" "<<p->data.CBuy<<" "<<p->data.CGrade<<endl;elsecout<<"不存在此客户!"<<endl;cout<<"请输入购买的产品名和数量"<<endl;cin>>proname>>count;if(flag1&&flag2)for(i=0,j=0; pi->data.CPN.mounti>0; i+,j+)if(pi->data.CPN.ProNamej=proname)pi->data.CPN.mounti = pi->data.CPN.mounti+count;if(pi->data.CPN.mounti<0)pi->data.CPN.mounti = count;pi->data.CPN.ProNamej = proname;if(flag1)for(i=0; i<16; i+)if(proname = productioni.PName)if(p->data.CGrade>=50&&p->data.CGrade<=100)p->data.CBuy = p->data.CBuy + count*productioni.PPrice*0.95;p->data.CGrade = p->data.CGrade/2;else if(p->data.CGrade>100)p->data.CBuy = p->data.CBuy + count*productioni.PPrice*0.85;p->data.CGrade = p->data.CGrade/2;elseif(count>3)p->data.CBuy = p->data.CBuy +count*productioni.PPrice; p->data.CGrade=p->data.CGrade+count*productioni.PGrade+count-3;elsep->data.CBuy = p->data.CBuy +count*productioni.PPrice;p->data.CGrade = p->data.CGrade+count*productioni.PGrade;2.2.7 修改客户信息函数函数原型:void recompose(LinkList L,string numb)此函数首先会打印用户要修改的客户信息,然后再打印出一个子菜单让用户选择不同的功能,进行修改该客户不同的信息,然后要求用户输入要选择的功能的编号。用户只需按照系统给出的提示,就可以修改客户的信息。2.3算法及平台分析 本系统用到的算法主要有链表的前插法、后插法及搜索等基本算法,没有用到其它比较复杂的算法,操作起来简单,并且容易控制;还用到输入输出流的一些操作来使显示的信息对称,不凌乱;再就是一些文件操作,更改存储文件中的容,保存操作后的所有信息。本系统是在Microsoft Visual C+ 6.0上设计及运行的,所有的信息显示均是在dos界面中显示出来,利用system("color 0B")操作使主界面以黑色为背景,前景色为亮蓝色,而其它界面显示及字的显示均为绿色。并且在每一步操作后,都利用system("cls")对dos界面进行清屏,使显示器显示的信息清晰、整齐。3实现方法通过对设计题目的深入分析,及题目的要求,在设计时,主要实现八大功能模块,大致满足一个客户消费积分管理系统系统的基本需要,主要的流程及实现方法请看下面的报告。3.1客户消费积分管理系统系统框架图客户消费积分管理系统返回首面查询客户消费状况 退出系统购买产品显示所有客户信息修改客户信息查询客户信息增加或删除客户客户编号客户名称客户消费产品星客户信息客户身份证号产品名称客户姓名客户消费金额消费产品数量客户积分3.2 客户消费积分管理系统系统主函数流程图结束修改客户信息显示所有客户信息退出系统购买产品返回首面查询客户消费状况初始化录入函数显示函数输入work值switch(work)开始查询客户信息增加或删除客户4 调试问题在制作和编写系统的过程中,碰到不少问题。在着手写代码时,我首先把主界面设计好,并按照主界面上显示的各种功能设计各个函数,这样不至于太盲目了。可是当我测试主界面时,出现了好多问题,出现好多函数没有声明的错误,然后把所有的屏蔽掉,就可以运行了。接着就是写第一个读取文件中的信息的函数,本想用二进制进行读写操作,但是使用之后,输出的信息全是些乱码,最后也只能确定用ASCII码进行读写了。在写到购买产品函数的时候,由于每一次购买后,都要把信息储存到文件中去,所以要用到写入文件操作,但是由于项目比较多,所以在编写代码的时候漏掉了终点时间没有写入,所以在保存后,退出系统后重新启动系统时,读入函数读入客户信息和客户消费信息时,在文件中所能读到的信息就缺少了一项,所以会把后面的信息读入到链表的头表中去,从而使数据读入时出现交错错误,使一些变量没有读得信息,从而在显示的时候,就会打印出乱码,这个错误在我找了好久,才从文件的数据中找到。还有个问题就是显示方面的。在写那些函数时,总会清屏上一次的屏幕,把函数写完之后,也会做同样的工作,所以在运行到system(“cls”)时,就会清除屏幕信息而显示其它容。所以要想清晰看到每次操作的信息,就要延迟system(“cls”)的执行。在没有做处理之前,总会出现一闪而过的现象,一瞬即逝,根本看不清所要显示的信息。在system(“cls”)前加上两行getchar()函数,它会吸收一个回车,然后再等待用户输入一个字符来结束当前的操作,所以在用户进入下一个操作时,按下任意一个键就行了。这使得用户可以看清自己想要的信息,做好下一步操作的准备工作。当然,在编写代码调试程序的时候,还碰到很多大大小小的问题,但在自己一遍又一遍的调试中改正了,从而使系统的功能更加完善,使系统的功能更从人性化,容错能力更加强大。但是系统还有可能有这样或那样的问题,只是自己没有发现,在测试过程中,没有用到一些特别的样例,可能会使系统崩溃,我想这也是可能的,希望老师加以指正和指导。5 系统的使用说明书对于整个系统的使用及每一次你所作出选择和操作之后会出现什么样的界面及操作结果,在下面的说明中作出详细的说明及展示,具体如下所示。5.1 主界面说明当运行系统时,首先进入的是主界面,显示了整个系统所提供的功能选项,在最后一行有提示让您输入你所要选择的功能项。如下所示:5.2 查询客户信息功能介绍根据系统的提示选择主界面的功能的序号,输入查询客户信息功能的序号1回车,系统就会打印出客户信息。5.3 增加或删除功能介绍根据系统的提示选择主界面的功能的序号,键入2进行增加或删除功能的操作,但是这个时候,系统会打印出一个信息对用户进行提示,若用户要求进行删除操作就需要客户键入1,若客户要求进行增加客户的操作就需要用户键入2,删除的具体操作如下所示用户若是增加客户,键入2时,系统会打印出一些增加客户所需要的输入的信息,用户需要按照系统给出的提示,输入客户的信息,添加成功后系统会打印出增加成功的字样进行提示,增加客户的操作如下所示5.4 修改客户信息功能介绍首先根据系统的提示选择主界面的功能的序号,键入3回车后,系统会弹出一个修改客户信息的子菜单和要修改的客户的客户信息。用户可以按照子菜单上的功能编号进行选择,然后键入相应的编号。例如以下就是键入功能编号D之后,就可以修改客户的消费金额。根据系统提示键入新的客户消费金额。成功之后,系统会弹出提示修改成功!5.5 查询客户信息功能介绍首先根据系统的提示选择主界面的功能的序号,键入4回车后,用户就可以看到所有客户的信息资料。5.6 购买产品功能介绍选择购买产品功能,需要首先根据系统的提示选择主界面的功能的序号,键入5回车后,系统会弹出“请输入客户的”提示,用户就需要填写客户的,回车之后系统会弹出该客户的一些信息,然后系统给出提示,要用户填入需要购买的产品的名称和数量。购买之后系统会弹出“购买成功”的提示。5.7 查询客户消费资料功能介绍首先根据系统的提示选择主界面的功能的序号,键入6回车后,系统会弹出“请输入客户的”提示,用户就需要填写客户的,回车之后系统会弹出该客户的一些消费记录信息。5.8 退出系统功能首先根据系统的提示选择主界面的功能的序号,键入8回车后,系统就会弹出“是否确定退出,是,请输入yes,否请输入no!:”提示,需要用户根据选择进行键入。最后系统会询问用户是否要对之前的一些操作,进行保存,如果需要的话,用户可以根据提示,键入yes,如果不需要保存的话,用户可以根据提示,键入no。系统就不会保存之前的一切操作而退出系统。6 结论经过几天的忙碌,最终把课程设计任务完成了。要做好一件事,只能一步一步的去做,不可能一下子就完成。本来以为简单的几个功能,要实现以为很容易,至多一天就可以做完,可是在真正实现、编写代码的过程却发现有太多的问题没有解决。比如要存储哪些数据,用什么方式存储;用怎么样的结构去保存各种数据等。要做好一个系统,一个严谨的思维是不可以或缺的,每一个联系都要考虑,每个细节都需要注意,每一种错误都要会解决。只有把每一种问题都解决了,才能做出一个完善的系统出来。参考文献1谭浩强.C程序设计(第三版). : 清华大学,20052严蔚敏著.吴伟民.数据结构(C语言版). : 清华大学,20073谭浩强著.C+程序设计. :清华大学,2004.6源代码:(注:此处包含两个文件1、main.cpp 2、head.h ,将代码分边写入两个文件中置于一个目录下)Main.cpp代码如下:#include <iostream>#include <string>#include <fstream>#include "head.h"using namespace std;void face()cout<<"="cout<<"* ÷ÈÁ¦¾Æ°É(¿Í»§Ïû·Ñ»ý·Ö¹ÜÀíϵͳ) *"cout<<"*±¾¾Æ°ÉÌṩµÄ²úÆ·ÈçÏ£º *"cout<<"* Æ¡ ¾Æ *Çൺơ¾Æ *Ñྩơ¾Æ *Ñ©»¨Æ¡¾Æ *"cout<<"* *°ÙÍþÆ¡¾Æ *"cout<<"* °×¾Æ *ÀÉ¾Æ *·Ú¾Æ *ę́ *"cout<<"* *ÎåÁ¸Òº *½ðÁù¸£ *¾Æ¹í¾Æ *"cout<<"* ºì¾Æ *À·Æºì¾Æ *ÏãéÄ *»ªÏij¤³Ç *"cout<<"* *ÍþÁú *ÕÅÔ£ *¹Ú½Ý *"cout<<"*=*"cout<<"*ÇëÑ¡Ôñ±¾ÏµÍ³ÌṩÒÔϹ¦ÄܵÄÐòºÅ *"cout<<"* 1¡¢²éѯ¿Í»§ÐÅÏ¢ 2¡¢Ôö¼Ó»òɾ³ý¿Í»§ *"cout<<"* 3¡¢Ð޸Ŀͻ§ÐÅÏ¢ 4¡¢ÏÔʾËùÓпͻ§ÐÅÏ¢ *"cout<<"* 5¡¢¹ºÂò²úÆ· 6¡¢²éѯ¿Í»§Ïû·Ñ×´¿ö *"cout<<"* 7¡¢·µ»ØÊ×Ãæ 8¡¢Í˳öϵͳ *"cout<<"="void recompose(LinkList L,string numb)LNode *p = L->next;char ch;float cont;string str;while(p)if(p->data.CCardNumber=numb)break;else if(p->data.CNumber=numb)break;else if(p->data.CName=numb)break;p = p->next;if(p)cout<<"ÄúÒªÐ޸ĵĿͻ§ÐÅÏ¢:"<<p->data.CCardNumber<<" "<<p->data.CNumber<<" "<<p->data.CName<<" "<<p->data.CBuy<<" "<<p->data.CGrade<<endl;cout<<"*"<<endl;cout<<"A¡¢Ð޸Ŀͻ§±àºÅ "<<"B¡¢Ð޸Ŀͻ§Éí·ÝÖ¤ºÅ "<<endl; cout<<"C¡¢Ð޸Ŀͻ§Ãû³Æ "<<"D¡¢Ð޸Ŀͻ§Ïû·Ñ½ð¶î "<<endl;cout<<"E¡¢Ð޸Ŀͻ§»ý·Ö "<<endl;cout<<"*"<<endl;cout<<"ÇëÑ¡Ôñ¹¦ÄܱàºÅ: "cin>>ch;switch (ch)case'A':case'a':cout<<"ÊäÈëеĿͻ§±àºÅ: "cin>>str;p->data.CCardNumber = str;cout<<"Ð޸ijɹ¦!"<<endl;break;case'B':case'b':cout<<"ÊäÈëеĿͻ§Éí·ÝÖ¤ºÅ: "cin>>str;p->data.CNumber = str;cout<<"Ð޸ijɹ¦!"<<endl;break;case'C':case'c':cout<<"ÊäÈëеĿͻ§Ãû³Æ: "cin>>str;p->data.CName = str;cout<<"Ð޸ijɹ¦!"<<endl;break;case'D':cout<<"ÊäÈëеĿͻ§Ïû·Ñ½ð¶î: "cin>>cont;p->data.CBuy = cont;cout<<"Ð޸ijɹ¦!"<<endl;break;case'E':case'e':cout<<"ÊäÈëеĿͻ§»ý·Ö: "cin>>cont;p->data.CGrade = cont;cout<<"Ð޸ijɹ¦!"<<endl;break;default:cout