当前位置:文档之家› 【电信计费系统客户帐单管理】电信账单

【电信计费系统客户帐单管理】电信账单

【电信计费系统客户帐单管理】电信账单程序设计报告( xx / xx 学年第二学期)题目:专学生班级指导指导日电信计费系统客户帐单管理业姓名学号教师单位计算机软件教学中心期 xx 年05月29日电信计费系统客户帐单管理一、课题内容和要求客户帐单管理是电信计费系统必备的重要功能模块,主要负责对电信各类客户每月帐单的增加、修改、删除、查询、备份等管理工作。

本课题以中国电信企业客户帐单管理模块原型参照,要求基于单链表结构对文件存储的客户帐单数据进行排序、查找、计算、显示等造作。

通过此可以,熟练掌握单链表结构、文件读写、函数调用等知识,以及查找、排序典型算法的设计与应用。

二、需求分析要能提供以下几个基本功能:(1)用户文件与话单文件由程序设计人员预先从键盘上录入,用户资料文件中的数据记录不得少于30条,话单文件中的数据记录不得少于200条,且必须有跨月份、跨年份的通话记录话单。

(2)首先从硬盘读入用户资料和话单记录(3)对话单进行计费处理,输出费用详单到指定的文件。

格式如下:电话号码用户姓名月租费功能费市内电话费用长途电话费用合计 83470000 Zhang Qiang 25.00 6.00 xxxxx xxxxx xxx 83470001 。

(4)异常话单提示。

有的话单可能是错误的,找出这些话单,不参加计费,另存为一个文件。

可能的出错话单有:①一个号码的通话时长大于三天。

②一个号码在一个时间存在两条以上的记录。

功能框架图如图1所示(1)提供可操作的主菜单:输出个菜单,用于显示以从文件中加载的总客户信息和若干个可选的功能选项。

根据客户输入的选项来运行不同的功能,运行不同的函数。

(2)显示所有用户的功能:根据选项可将文本里的用户信息在屏幕上显示出来。

(3)显示所有账单功能:可将文本里的通话账单在屏幕上显示出来。

(4)添加用户功能:可在屏幕上进行直接操作,将用户信息添加到记录里。

(5)添加账单功能:操作同上,可将新的通话记录添加到记录里。

(6)按用户民查找功能:输入记录里的用户民,可以查询与之相关的通话账单记录。

(7)按电话号码查找功能:输入记录里的已有电话号码,可以查找相应的通话账单记录。

(8)输出花费功能:在操控台和文本中,直接输出所有的花费详情。

三、概要设计1、主要函数流程图如图2所示:图2:主程序图图3:操作菜单系统图4:显示所有信息菜单图5:插入数据菜单图6:计算话费函数图7::判断话费正误函数1、顾客类(Customer ):#include#include#include //控制输出格式 class Customer //定义一个顾客类 {protected: char Name[20]; //用户名 char Number[15]; //用户电话号码 char CID; //是否来电显示 public: Customer(char* =" ",char* =" " ,char cid=" "); //定义构造函数 ~Customer(); //定义析构函数 Customer(const Customer & obj); //定义拷贝构造函数 char* GetName(); //获得用户名字符型指针函数 char* GetNumber(); //获得用户号字符型指针函数 char GetCID(); //看用户是否有来电显示 friend istream & operator >> (istream & in , Customer & cus);//友元重载输入friend ostream & operator};Customer::Customer(char *na, char *num,char cid){ strcpy( Name , na ); strcpy( Number , num ); CID=cid; }Customer::~Customer() { }Customer::Customer( const Customer & obj ) //构造函数的定义 { strcpy( Name , ); strcpy( Number , obj.Number ); CID=obj.CID; }char* Customer::GetName() { return Name; }char* Customer::GetNumber() { return Number; }char Customer::GetCID() { return CID; }istream & operator >> (istream & in,Customer & cus){ in>>; //输入用户名 in>>cus.Number; //输入用户号码in>>cus.CID; //来电业务信息 return in; }//友元重载ostream & operator2、话单类(Bill ):#include #include #include #include class Bill {protected: char Dialing[15]; char Dialed[15]; char StartTime[15]; char EndTime[15]; public: Bill(char *dialing=" ",char *dialed=" ",char *stime=" ",char *etime=" ");//定义构造函数~Bill(); Bill( const Bill & obj); //帐单的拷贝构造函数char* GetDialing(); //获得主叫号码 char* GetDialed(); //获得被叫号码 char* GetStart(); //获得起始时间 char* GetEnd(); //获得结束时间 int GetDate(); //获得日期 int GetTime(); //获得通话时长 friend int mon_day(int year,int month); //记录不同月份的天数 friend istream & operator >> (istream & in ,Bill & bill); //友元重载输入 friend ostream & operatorBill::Bill(char *dialing,char *dialed,char *stime,char*etime) { strcpy( Dialing , dialing ); strcpy( Dialed , dialed );strcpy( StartTime , stime );strcpy( EndTime , etime );}Bill::Bill(const Bill & obj){strcpy( Dialing , obj.Dialing );strcpy( Dialed , obj.Dialed );strcpy( StartTime , obj.StartTime ); strcpy( EndTime , obj.EndTime );}Bill::~Bill(){}char* Bill::GetDialing() {return Dialing;}char* Bill::GetDialed() {return Dialed;}char* Bill::GetStart() {return StartTime;}char* Bill::GetEnd(){return EndTime;}istream & operator >> (istream & in,Bill & bill) {in>>bill.Dialing;in>>bill.Dialed;in>>bill.StartTime;in>>bill.EndTime;return in;}ostream & operator {outoutoutoutoutoutreturn out;}int Bill::GetDate(){int Dat[6];double date=0;for(int i=0;i{Dat[i]=StartTime[i]-48; //文本文件读入时只能以字符型的形式,计算是转化成整形date+=Dat[i]*pow(10,5-i);return (int)date;}int Bill::GetTime(){return Estimate(StartTime,EndTime);}int mon_day(int year,int month) //记录不同月份的天数 {int day[12]; //d数组12个成员为12个月份day[0]=31; //给成员一一赋值if( year%4==0 && year%100!=0 || year%400 == 0 ) //判断是否是闰年day[1]=29;elseday[1]=28;day[2]=31;day[3]=30;day[4]=31;day[5]=30;day[6]=31;day[7]=31;day[8]=30;day[9]=31;day[10]=30;day[11]=31;return day[month-1]; //返回y 年m 月有多少天}int Estimate(char *m,char *n) //判断时间正误函数 {int a[14],b[14]; //a记录开始时间,b 记录结束时间 for(int i=0;i{a[i]=m[i]-48;b[i]=n[i]-48;}int y1,mon1,d1,h1,min1,s1; //开始时间的年月日时分秒int y2,mon2,d2,h2,min2,s2; //结束时间的年月日时分秒int x,y; //开始、结束时间的日、时、分统一换算成分钟,对应着x 、yy1=a[0]*1000+a[1]*100+a[2]*10+a[3]; //开始时间的年份mon1=a[4]*10+a[5]; //开始时间的月份d1=a[6]*10+a[7]; //开始时间的日期h1=a[8]*10+a[9]; //开始时间的时min1=a[10]*10+a[11]; //开始时间的分s1=a[12]*10+a[13]; //开始时间的秒x=d1*24*60+h1*60+min1;y2=b[0]*1000+b[1]*100+b[2]*10+b[3]; //结束时间的年份 mon2=b[4]*10+b[5]; //结束时间的月份d2=b[6]*10+b[7]; //结束时间的日期h2=b[8]*10+b[9]; //结束时间的时min2=b[10]*10+b[11]; //结束时间的分s2=b[12]*10+b[13]; //结束时间的秒y=d2*24*60+h2*60+min2;if( mon1>12 ||mon112 ||mon2h1>23 ||h123 ||h159 ||min1||min2>59 ||min259 ||s159 ||s2mon_day(y1,mon1) ||d2>mon_day(y2,mon2)){return -1; //如果“月,日,时,分,秒”超出范围,则返回-1 }else{if(y1==y2) //判断同年{if(mon1==mon2) //判断月份{if( (y-x0) ) //判断通话在三天内{钟计算的,否则错误误时间大一月if(s1s1) //结束秒数大于开始秒数,就是正确 return 1; else { cout}else //不同年的情况{if(y2-y1==1&&mon1==12&&mon2==1) //不同年只能是去年的12 月,当年的1月结束{if(s1{return y-x+1+31*24*60;}else{return y-x+31*24*60;}}else{coutreturn -1;}}}}四、源程序代码.#include"Customer.h"#include"Bill.h"#include#includedouble PrepaidFee=25.0,Cid=6.0,Local=0.1,Toll=0.7;//定义全局变量:月租, 来电显示费用市内电话单价和长途电话单价const int Max=2000; //最大数组长度char ShowMainMeun(); //显示主菜单char ShowSonMenu(); //显示子菜单void ShowCustomer(); //显示所有客户信息void ShowBill(); //显示所有帐单信息void AddCusInfo(); //添加用户信息void AddBilInfo(); //添加帐单信息void SearchCusInfo(); //按照客户查找帐单信息void SearchNumInfo(); //按照号码查找帐单信息void Calculate(Customer *cus,Bill *bill ,int m,int n);// void ShowAll(); //输出所有帐单信息void ShowWrongMess(Bill *bill,int n);//输出错误帐单的信息bool Compare(int m,int *p,int n); //如果m 与数组p[n]的任何一个数都不相等,那么就返回falseint Judge(Bill *bill,int m,Bill bil,int n); //判断bil 帐单是否会发生冲突char ShowMainMeun(){coutcout=========================================================== ="coutcoutcoutcoutcoutcoutcoutcoutcoutcoutcout=========================================================== ="cout合计"coutchar choice;coutcin>>choice; //用户输入操作选项return choice; //返回操作选项}char ShowSonMenu(){cout=========================================================== ="coutcoutcoutcout|"cout|"cout=========================================================== ="char choice;coutcin>>choice; //用户输入操作选项 return choice; //返回操作选项}void ShowCustomer(){coutCustomer Cus[Max];Bill bill[Max];ifstream inf1("用户信息.txt"); int count1=0;while (!inf1.eof()){inf1>>Cus[count1];coutcount1++;}ifstream inf2("话单信息.txt"); int count2 =0;while (!inf2.eof()){inf2>>bill[count2];count2++;}inf1.close();inf2.close();char point;while((point=ShowSonMenu())!="0"){if(point=="1")Calculate(SaveCus,SaveBill,2,count2); else if(point=="2")ShowWrongMess(bill,count2);elsecout}}void ShowBill(){Customer Cus[Max];Bill bill[Max];ifstream inf1("用户信息.txt"); |int count1=0;while (!inf1.eof()){inf1>>Cus[count1];count1++;}ifstream inf2("话单信息.txt"); int count2 =0;while (!inf2.eof()){inf2>>bill[count2];coutcount2++;}inf1.close();inf2.close();char point;while((point=ShowSonMenu())!="0"){if(point=="1")Calculate(SaveCus,SaveBill,2,count2); else if(point=="2")ShowWrongMess(bill,count2);elsecout}}void ShowAll(){Customer Cus[Max];Bill bill[Max];ifstream inf1("用户信息.txt");int count1=0;while(!inf1.eof()) //录入顾客信息到Customer 类的数组cust 中 {inf1>>Cus[count1];count1++; //有m-1个顾客}int count2=0;ifstream inf2("话单信息.txt");while(!inf2.eof()) //录入账单记录到Bill 类的数组bill 中 {inf2>>bill[count2];count2++; //有n 个账单记录}inf1.close(); //关闭文件inf2.close(); //关闭文件Calculate(Cus,bill,count1,count2); }void AddCusInfo(){Customer Cus[Max];int num;coutcin>>num;coutfor( int n=0;ncin>>Cus[n]; //输入添加的用户名ofstream outf;outf.open("用户信息.txt",ios::app); //用app 方式打开文本,能直接在文本尾加入信息for(n=0;noutfcoutoutf.close();}void AddBilInfo(){Bill bill[Max];int num;coutcin>>num;coutcoutfor( int n=0;ncin>>bill[n];ofstream outf;outf.open("话单信息.txt",ios::app); //用app 方式打开文本,能直接在文本尾加入信息for(n=0;noutfcoutoutf.close();}void SearchCusInfo() {char Name[20];coutcin>>Name;Customer Cus[Max]; Bill bill[Max];ifstream inf1("用户信息.txt");int count1=0;while (!inf1.eof()) //录入顾客信息到Customer 类数组Cus 中 {inf1>>Cus[count1];count1++; //记录总共有(count1-1)个顾客 } ifstream inf2("话单信息.txt"); int count2 =0; while (!inf2.eof()){ inf2>>bill[count2]; count2++; //总共有count2条话单 }inf1.close(); inf2.close(); Customer SaveCus[1]; Bill SaveBill[Max]; //保存该用户的话单信息 int i=0,j=0,k=0; coutcout}}void SearchNumInfo(){Customer Cus[Max];ifstream inf1("用户信息.txt"); int count1=0;while (!inf1.eof()){inf1>>Cus[count1];count1++; //有count1-1个用户}Bill bill[Max];ifstream inf2("话单信息.txt");int count2 =0;while (!inf2.eof()){inf2>>bill[count2];count2++; //有count2条话单记录 }inf1.close();inf2.close();char Number[15];coutcin>>Number;Bill SaveBill[Max];int i=0,j=0,k=0;coutbool p=true;for(i=0;i{if(strcmp(bill[i].GetDialing(),Number)==0) {coutj=false;SaveBill[k]=bill[i];k++;}}if(j)coutCustomer SaveCus[1];for(i=0;i{if(strcmp(Cus[i].GetNumber(),Number)==0) {SaveCus[0]=Cus[i];}}char point;while((point=ShowSonMenu())!="0"){if(point=="1")Calculate(SaveCus,SaveBill,2,count2); else if(point=="2")ShowWrongMess(bill,count2);elsecout}}void Calculate (Customer *cus,Bill *bill,int m,int n) {cout"ofstream outa("所有信息.txt");ofstream outw("错误账单.txt");for(int i=0;i{int a[Max]={0}; //int数组,用于记录已计算过的月份if(cus[i].GetCID()=="Y") //判断用户是否有功能费Cid=6;elseCid=0;for(int j=0;j{if( strcmp( cus[i].GetNumber() , bill[j].GetDialing() ) == 0 ) //找出cust[i]客户的所有帐单{double local=0,toll=0,sum=0; //一个月的市话费、长途费及总电话费if(Compare(bill[j].GetDate(),a,n )) //判断在记录a[n]中是否存在 bill[j].getdate() 记录,若存在,则跳过这条账单信息continue;else{for(int k=j;k{if((bill[j].GetDate()==bill[k].GetDate())&&( strcmp(cus[i]. GetNumber(),bill[k].GetDialing()) == 0 ) ) //若bill[k]的月份与主叫电话号码都相同,则计算这个月的电话费{if(bill[k].GetTime()>=0&&Judge(bill,n,bill[k],k)==1){if( strlen( bill[k].GetDialed() )>8 ) // 按照市话来看,长度大于8的都算是长途电话 toll += bill[k].GetTime()*Toll;elselocal += bill[k].GetTime()*Local;a[j]=bill[j].GetDate();存到a[n]中}else{outw}}}sum=PrepaidFee+Cid+toll+local; //文本输出outa。

相关主题