-电信计费系统客户帐单管理一、课题内容和要求客户帐单管理是电信计费系统必备的重要功能模块,主要负责对电信各类客户每月帐单的增加、修改、删除、查询、备份等管理工作。本课题以中国电信企业客户帐单管理模块原型参照,要求基于单链表结构对文件存储的客户帐单数据进行排序、查找、计算、显示等造作。通过此可以,熟练掌握单链表结构、文件读写、函数调用等知识,以及查找、排序典型算法的设计与应用。二、需求分析功能框架图:(见图2-1)电信计费系统客户帐单管理查找插入删除修改备份保存排序统计图2-11)提供可操作的主菜单:输出个菜单,用于显示以从文件中加载的总客户信息和若干个可选的功能选项。根据客户输入的选项来运行不同的功能,运行不同的函数。2)进行文本信息的载入:从指定的文件中以链表形式加载所需的客户信息并建立链表。这里的文件是在编译时就已经指定好的、存在的文本,需设计者预先自己建立好。3)查找客户功能:以客户输入的客户名称进行查找对应的客户信息并将它们输出。可通过所建立的链表进行对应的查找。4)添加一个新的客户功能:将客户希望添加的客户信息添加到指定的客户信息之前。应提示客户按照正确的格式输入。并建立添加链表结点的函数将客户信息加入。-5)删除一个客户的功能:将客户希望删除的某个客户信息删除。(这里的删除只是才内存中建立的链表中删除,在保存之前待删客户的信息还储存在原文本只中的。)6)进行客户信息的修改:根据客户提供的名称,找到对应的链表,将链表中的信息重置。内容应有客户输入,由一系列读写函数实现。7)对现有信息的保存:保存内存中的最新的记录输出到磁盘文件中。这里默认的是保存到原读取文件中并覆盖原来的信息。8)将信息备份到另外的一个文本中:通过文件格式读写函数,将源文件信息写到客户提供的目标文件中。(C++在存储时可自动建立文件,可以不事先建立好。)9)将客户排序功能:根据客户标识升序排列。可以用冒泡法实现。10)分类合计功能:根据排序的结果,分别统计并显示本地网级和营业区级的市话费小计、长话费小计、通话费合计、客户帐单数量。应注意每个名称的单一性,不可输出同一个名称。三、概要设计1)主要结构体:structtype{//客户帐单结构intcustbillid;//客户帐单编码charcustname[50];//客户名称doublelocalfee;//市话费用doubleidfee;//长话费用charlatnname[20];//本地网名称charregionname[30];//营业区名称structtype*next;//指针}*head,*p1;//全局指针-2)主要函数流程图:(1)装载函数:用于从文本中载入信息并建立链表,此处用链表方式读入,用(structtype*)malloc(sizeof(structtype))来动态建立链表结点树目,此处以一个结构体内容作为一个结点。(见图3-1)开始打开文本能否打开否是申请空间读入数据否是否结束删除多出的一个结点是结束开始结束读入名称名称符合判断否是否结束否指向下一结点未找到是是输出信息图3-1图3-2(2)查找函数:利用用户输入的名称进行顺序查找并将找到的客户信息输出。(见图3-2)(3)插入函数:在用户指定的目标前插入用户希望加入的客户及其信息。(见图3-3)-开始结束调用查找函数以p1指向结点动态申请空间p2空间指针的next指向找到的位置读入各个量的信息所找到的是否是头位置Head=p2是否P3-next==p1建立P3=head;p3指向下一结点否P3-next=p2是开始结束读入名称指针指头名称不同是否结束是指针p2=p1;p1指下一结点否是否为头部否head后移一位是p2-next=p1-next否图3-3图3-4(4)删除函数:将指定的客户从链表中删除(见图3-4)(5)修改函数:修改指定客户的信息(见图3-5)(6)保存文件函数:将最新的内容通过文件读写,从内存中保存到原文本文件中(见图3-6)-开始调用查找函数输出提示信息读入各个量的信息并覆盖原信息输出操作完成提示结束开始打开文件成功指针指头向文件中写入各个量信息,信息间加空格是指针指下一结点是否结束否结束是否图3-5图3-6(7)备份文件函数:将文件内容存贮到用户给定的地址中(见图3-7)开始读入给定位置判断能否打开结束否指针指头是是否结束是写入各个量的内容否指针指下一结点(图3-7)-(8)排序函数:将客户的顺序按照客户编号用冒泡法进行升序排列(见图3-8)开始建立与各个量对应的中间变量(M)指针指头是否结束指针指下一结点;计数器加一;否i=计数器?j计数器?是指针编码下一结点编码?是通过(M)交换各个量的内容是指针指下一结点;j++;否指针指头;i++;结束变量i=1变量j=i否是开始建立二维字符数组M;结构体指针P2;变量i=0,j=0和3个计数器;输出表头指针指头ji&&未结束接点名称与M[j]相同是是指针指下一结点;j=-1j++否未结束否P2指当前指针;将名称copy给M[i];i++;是输出名称P2未指尾名称相符计数器累加是否P2指下一结点否是计数器清零;指针指下一结点输出计数器信息未指尾否结束是否图3-9图3-10-(9)统计函数:根据排序的结果,分别统计并显示本地网级和营业区级的市话费小计、长话费小计、通话费合计、客户帐单数量。,此处用strcmp函数对名称进行判断,并将未存储的名称做记录。找到相同名称的结点时进行累加。(此处给出本地网级的流程图,营业区级与其类似。见图3-10)四、源程序代码#includefstream.h#includestdlib.h#includestring.h#includeiomanip.hstructtype{//客户帐单结构intcustbillid;//客户帐单编码charcustname[50];//客户名称doublelocalfee;//市话费用doubleidfee;//长话费用charlatnname[20];//本地网名称charregionname[30];//营业区名称structtype*next;//指针}*head,*p1;/*装载函数,用于从文本中载入信息并建立链表,此处用链表方式读入,用(structtype*)malloc(sizeof(structtype))来动态建立链表结点树目,此处以一个结构体内容作为一个结点(在文本中应为一行的内容)*/intloadcustbill(){structtype*p2;ifstreamifs(d:\\123.txt);if(!ifs){coutcan'topen\n;return1;}p1=(structtype*)malloc(sizeof(structtype));if(p1==NULL)exit(0);head=p1;if(!ifs.eof())ifsp1-custbillidp1-custnamep1-localfeep1-idfeep1-latnnamep1-regionname;p1-next=NULL;while(!ifs.eof()){p2=(structtype*)malloc(sizeof(structtype));-if(p2==NULL)exit(0);ifsp2-custbillidp2-custnamep2-localfeep2-idfeep2-latnnamep2-regionname;p2-next=NULL;p1-next=p2;p1=p2;}p1=head;while(p1-next-next!=NULL)//因使用!ifs.eof()判断结束时会多度出一行,导致链p1=p1-next;//表接点多出,在次删除最后一个p1-next=NULL;ifs.close();return1;}/*菜单函数,输出提示信息供客户选择*/voidmenu(){cout菜单:\n;p1=head;cout总客户信息:\n;while(p1!=NULL){coutp1-custbillidsetw(10)p1-custnamesetw(10)p1-localfeesetw(10)p1-idfeesetw(10)p1-latnnamesetw(10)p1-regionnameendl;p1=p1-next;}cout请输入所要进行的操作:\n1:查找客户;\n2:插入帐单;\n3:删除帐单;\n4:修改帐单;\n5:保存帐单;\n6:备份帐单;\n7:客户排序;\n8:分类合计;\n9:显示菜单\n0:推出操作;\n;}/*查找函数,找到并输出客户所要的客户信息*/voidsearchbyname(){charname[50];cout请输入所要寻找的客户名称:;cinname;p1=head;while(strcmp(name,p1-custname)!=0)//利用strcmp将名称进行对比以确定目标位置if(p1-next!=NULL)p1=p1-next;else{coutcan'tfindyourname!;exit(0);-}cout以找到客户对象\n;if(p1-next!=NULL)coutcustbillid:p1-custbillid\ncustname:p1-custname\nlocalfee:p1-localfee\nidfee:p1-idfee\nlatnname:p1-latnname\nregionname:p1-regionnameendl;cout操作已完成,请继续操作\n;}/*添加客户函数,建立在查找的基础上,动态申请一个空间并通过cin来进行赋值。在插入目标前方时要判断目标是否为头位置。*/voidinsert(){structtype*p2,*p3;cout确认位置,;searchbyname();//调用searchbyname()来确定位置p2=(structtype*)malloc(sizeof(structtype));if(p2==NULL)exit(0);cout请依次输入:客户帐单编码,客户名称,市话费用,长话费用,本地区名称,营业区名称\n;p2-next=p1;cinp2-custbillidp2-custnamep2-localfeep2-idfeep2-latnnamep2-regionname;if(p1==head)head=p2;else{p3=head;while(p3-next!=p1)p3=p3-next;p3-next=p2;}cout操作已完成,请继续操作\n;}/*删除客户函数*/voiddeletebill(){structtype*p2;charx[50];cout请输入需要删除的客户名称:\n;cinx;p1=head;while(strcmp(x,p1-custname)!=0)if(p1-next!=NULL){p2=p1;p1=p1-next;-}else{coutcan'tfindyourname!;exit(0);}if(p1==head)head=p1-next;elsep2-next=p1-next;cout操作已完成,请继续操作\n;}/*修改客户信息函数*/voidmodify(){searchbyname();cout请依次输入custbillid,custname,localfee,idfee,latnname,regionname\n;cinp1-custbillidp1-custnamep1-localfeep1-idfeep1-latnname