【实训项目】--《手机通讯录》
2015-07-16 23:47
411 查看
/* * Copyright (c) 2014, 烟台大学计算机学院 * All rights reserved. * 文件名称:test.cpp * 作 者:刘畅 * 完成日期:2015 年 7 月 16 日 * 版 本 号:v1.0 *
《手机通讯录》之Telphone.h
#ifndef TELPHONE_H_INCLUDED #define TELPHONE_H_INCLUDED #include <iostream> //C++标准头文件 #include <fstream> //操作文件的头文件 #include <cstdlib> //exit()必要的头文件 #include <windows.h> //清屏函数必要的头文件 #include <shlobj.h> //MessageBox必要的头文件 #include <cstring> #include <iomanip> #include "Telphone.h" using namespace std; class Person; /* *类名称:PersonTel *说明:通讯录中联系人的数据 */ class PersonTel { public: PersonTel () {} //构造函数 void setPersonTel(char name[],int age,char sex[],char address[],char phone[]); //输入 friend ostream& operator<<(ostream& out, PersonTel& s); //重载运算符 friend class Person; //将Person声明为友元类 protected: char Name[20]; //姓名 int Age; //年龄 char Sex[4]; //性别 char Address[40]; //地址 char Phone[12]; //电话号码 }; /* *类名称:Person *说明:建立一个通讯录 */ class Person { public: Person(); ~Person(); void Establish(); //建立联系人信息 void Modification(); //修改联系人信息 void Display(); //显示联系人信息 void Query(); //查询联系人信息 void Delete(); //删除联系人信息 friend int KMP(char a[],char b[]); //将KMP声明为友元函数 protected: PersonTel Per[500]; //最多保存500位联系人 int NUM; //联系人总数 }; #endif // TELPHONE_H_INCLUDED
《手机通讯录》之Telphone.cpp
#include <iostream> //C++标准头文件 #include <fstream> //操作文件的头文件 #include <cstdlib> //exit()必要的头文件 #include <windows.h> //清屏函数必要的头文件 #include <shlobj.h> //MessageBox必要的头文件 #include <cstring> #include <iomanip> #include "Telphone.h" using namespace std; /* *函数名称:setPersonTel *功能描述:将要保存的联系人信息保存到类中. *输入参数:name-姓名,age-年龄,sex-性别,address-地址,phone-电话 *输出参数:Name-姓名,Age-年龄,Sex-性别,Address-地址,Phone-电话 *返回值:无 *其他说明: */ void PersonTel::setPersonTel(char name[],int age,char sex[],char address[],char phone[]) { strcpy(Name,name); Age=age; strcpy(Sex,sex); strcpy(Address,address); strcpy(Phone,phone); } /* *函数名称:Person *功能描述:构造函数 *输入参数:文件中的数据 *输出参数:对象Person中的数据成员类PersonTel构建的对象 *返回值:无 *其他说明:在构建一个Person对象的同时读取文件 */ Person::Person() //构造函数 { int num=0; ifstream infile("data.dat",ios::in|ios::binary); //打开二进制文件 if (!infile) //如果找不到文件输出打开失败并退出 { MessageBox(0,"open error!","提示",0); exit(1); } infile.read((char*)&Per[num],sizeof(PersonTel)); //二进制文件读取 while (!infile.eof()) //当没有达到文件末尾时 { num++; infile.read((char*)&Per[num],sizeof(PersonTel)); } infile.close(); //读入完毕一定要关闭文件; NUM=num; //将当前文件中联系人的数目赋值给NUM } /* *函数名称:~Person *功能描述:析造函数 *输入参数:对象Person中的数据成员类PersonTel构建的对象 *输出参数:以二进制数据格式存储到文件中 *返回值:无 *其他说明:在析构一个Person对象的同时存储数据到中文件 */ Person::~Person() //析构函数,保存数据 { ofstream data("data.dat",ios::binary); for (int i=0; i<NUM; ++i) data.write((char*)&Per[i],sizeof(Per[i])); //将数据以二进制格式写入文件 data.close(); //写入完毕一定要关闭文件; } /* *函数名称:KMP *功能描述:字符串匹配算法,判断一串字符串是否为另一串的子串 *输入参数:两串字符串。 *输出参数:如果匹配失败返回-1,匹配成功则返回其他值 *返回值:-1 OR others。 *其他说明:KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。 */ int KMP(char a[],char b[]) //匹配字符串KMP算法 { int i = 0; while(a[i]!='\0') { int tarlen = i; int patlen; for(patlen=0; b[patlen]!='\0'; patlen++) { if(a[tarlen++]!=b[patlen]) { break; } } if(b[patlen]=='\0') { return i; } i++; } return -1; } /* *函数名称 ostream& operator<<. *功能描述:重载函数,重载运算符<<. *输入参数:引用型输出流对象out和类PersonTel的对象s. *输出参数:联系人对象s的数据成员. *返回值: 引用型输出流对象out. *其他说明:. */ ostream& operator<<(ostream& out, PersonTel& s) //重载运算符<< { out<<s.Name<<"\t"<<s.Age<<"\t"<<s.Sex<<"\t"<<s.Address<<"\t\t"<<s.Phone<<endl; return out; } /* *函数名称:Establish *功能描述:新建功能,建立一个新的联系人 *输入参数:当前联系人总数以及新建联系人信息 *输出参数:新建联系人信息 *返回值: 无 *其他说明:将新建的联系人添加到文件的末尾 */ void Person::Establish() //建立联系人信息 { if (NUM==0) cout<<endl<<"当前联系人列表为空."<<endl<<endl; char name[20]; //姓名 int age; //年龄 char sex[4]; //性别 char address[40]; //地址 char phone[12]; //电话号码 do { int k=1; cout<<"请输入姓名:"; cin>>name; for (int i=0; i<NUM; ++i) { if (strcmp(Per[i].Name,name)==0) { MessageBox(0,"你输入的姓名已存在,请重新输入(添加备注).","提示",0); //通过调用MessageBox函数来实现窗口化错误提示 k=0; break; } } if (k==0) continue; else break; } while(1); cout<<"请输入年龄:"; cin>>age; cout<<"请输入性别:"; cin>>sex; cout<<"请输入地址:"; cin>>address; do { int k=1; cout<<"请输入电话号码:"; cin>>phone; for (int i=0; i<NUM; ++i) { if (strcmp(Per[i].Phone,phone)==0) { MessageBox(0,"你输入的电话号码已存在.","提示",0); //通过调用MessageBox函数来实现窗口化错误提示 k=0; break; } } if (k==0) continue; else break; } while(1); cout<<"姓名"<<"\t"<<"年龄"<<"\t"<<"性别"<<"\t"<<"家庭住址"<<"\t"<<"电话号码"<<endl; cout<<name<<"\t"<<age<<"\t"<<sex<<"\t"<<address<<"\t\t"<<phone<<endl; Per[NUM].setPersonTel(name,age,sex,address,phone); ofstream data("data.dat",ios::binary|ios::app); //将数据以二进制格式保存到文件末尾 data.write((char*)&Per[NUM],sizeof(PersonTel)); NUM++; data.close(); } /* *函数名称:Modification *功能描述:修改功能,通过搜索联系人姓名,修改联系人信息 *输入参数:二进制文件中的数据 *输出参数:联系人列表的所有成员及信息 *返回值: 无 *其他说明:使用了随机存储和修改,可直接修改那一行的数据 */ void Person:: Modification() //修改联系人信息 { int i,k,m; char name[20]; //姓名 int age; //年龄 char sex[4]; //性别 char address[40]; //地址 char phone[12]; //电话号码 do { k=-1; cout<<"请输入你想要修改对象的姓名(输入BACK退出):"; cin>>name; if (strcmp(name,"BACK")==0) break; for (i=0; i<NUM; i++) { if (strcmp(Per[i].Name,name)==0) { k=i; break; } } if (k==-1) { MessageBox(0,"你输入的对象不存在,请重新输入.","提示",0); //通过调用MessageBox函数来实现窗口化错误提示 continue; } else { cout<<"姓名"<<"\t"<<"年龄"<<"\t"<<"性别"<<"\t"<<"家庭住址"<<"\t"<<"电话号码"<<endl; cout<<Per[k]; do { cout<<"请选择你需要修改的内容:"<<endl; cout<<"1.姓名 2.年龄 3.性别"<<endl; cout<<"4.地址 5.电话 0.退出 "<<endl; cout<<"请输入操作指令:"; cin>>m; if (m==0) break; switch (m) { case 1: cout<<"请输入新的姓名:"; cin>>name; strcpy(Per[k].Name,name); cout<<Per[k]; continue; case 2: cout<<"请输入新的年龄:"; cin>>age; Per[k].Age=age; cout<<Per[k]; continue; case 3: cout<<"请输入新的性别:"; cin>>sex; strcpy(Per[k].Sex,sex); cout<<Per[k]; continue; case 4: cout<<"请输入新的地址:"; cin>>address; strcpy(Per[k].Address,address); cout<<Per[k]; continue; case 5: cout<<"请输入新的电话号码:"; cin>>phone; strcpy(Per[k].Phone,phone); cout<<Per[k]; continue; } } while (1); ofstream outfile1("data.dat",ios::binary|ios::ate|ios::in|ios::out); if(!outfile1) { cerr<<"open error"<<endl; exit(1); } outfile1.seekp(ios::beg); outfile1.seekp(sizeof(PersonTel),ios::beg); outfile1.seekp(k*sizeof(Per[k]),ios::beg); outfile1.write((char*)&Per[k],sizeof(Per[k])); outfile1.close(); } } while (1); } /* *函数名称:Display *功能描述:显示功能, *输入参数:二进制文件中的数据 *输出参数:联系人列表的所有成员及信息 *返回值: 无 *其他说明:无 */ void Person::Display() //显示联系人列表 { if (NUM==0) { MessageBox(0,"当前联系人列表为空.","提示",0); //通过调用MessageBox函数来实现窗口化错误提示 cout<<endl; } else { cout<<"姓名"<<"\t"<<"年龄"<<"\t"<<"性别"<<"\t"<<"家庭住址"<<"\t"<<"电话号码"<<endl; for (int i=0; i<NUM; i++) cout<<Per[i]; cout<<endl; } } /* *函数名称:Query *功能描述:查询功能,通过输入某个信息的部分内容,能够查询显示有相关内容的数据 *输入参数:二进制文件中的数据 *输出参数:与关键字有关的一组或多组数据 *返回值: 无 *其他说明:运用了KMP算法来实现子串匹配母串的功能 */ void Person::Query() //查询联系人信息 { int m,i=0; char name[20]; //姓名 int age; //年龄 char sex[4]; //性别 char address[40]; //地址 char phone[12]; //电话号码 do { bool flag=true; cout<<"1.姓名 2.年龄 3.性别"<<endl; cout<<"4.地址 5.电话 0.退出 "<<endl; cout<<"请输入操作指令:"; cin>>m; if (m==0) { break; } else if (m==1) { cout<<"请输入关键字:"; cin>>name; for (i=0; i<NUM; ++i) if (KMP(Per[i].Name,name)!=-1) { cout<<Per[i]; flag=false; } if (flag==true) MessageBox(0,"没有查询到相关内容.","提示",0); cout<<endl; } else if (m==2) { cout<<"请输入关键字:"; cin>>age; for (i=0; i<NUM; ++i) { if (Per[i].Age==age) { cout<<Per[i]; flag=false; } } if (flag==true) MessageBox(0,"没有查询到相关内容.","提示",0); cout<<endl; } else if (m==3) { cout<<"请输入关键字:"; cin>>sex; for (i=0; i<NUM; ++i) if (KMP(Per[i].Sex,sex)!=-1) { cout<<Per[i]; flag=false; } if (flag==true) MessageBox(0,"没有查询到相关内容.","提示",0); cout<<endl; } else if (m==4) { cout<<"请输入关键字:"; cin>>address; for (i=0; i<NUM; ++i) if (KMP(Per[i].Address,address)!=-1) { cout<<Per[i]; flag=false; } if (flag==true) MessageBox(0,"没有查询到相关内容.","提示",0); cout<<endl; } else if (m==5) { cout<<"请输入关键字:"; cin>>phone; for (i=0; i<NUM; ++i) if (KMP(Per[i].Phone,phone)!=-1) { cout<<Per[i]; flag=false; } if (flag==true) MessageBox(0,"没有查询到相关内容.","提示",0); cout<<endl; } } while (1); } /* *函数名称:Delete *功能描述:删除联系人 *输入参数:二进制文件中的数据 *输出参数:删除部分数据后的数据以二进制格式存储到文件中 *返回值: 无 *其他说明:新建一个newdata.dat文件用来做中介作用,将原文件中的数据除了要删除的数 据外保存到这个新文件中,然后再将新文件中的数据写入原文件,达到删除数据的作用 */ void Person::Delete() //删除联系人 { ifstream inData("data.dat", ios::in|ios::binary); ofstream outData("newdata.dat",ios::binary|ios::out); if (!outData || !inData) { cerr <<"open error" <<endl; exit(1); } char sign[16]; cout<<"你要删除联系人的姓名:"; cin >>sign; bool flag = true; int i=0; inData.read((char*)&Per[i],sizeof(PersonTel)); while (!inData.eof()) { if (strcmp(Per[i].Name,sign)==0) { cout<<endl<<"你想删除的联系人:"; cout<<Per[i]<<endl; i++; flag=false; inData.read((char*)&Per[i],sizeof(PersonTel)); continue; } outData.write((char*)&Per[i],sizeof(PersonTel)); i++; inData.read((char*)&Per[i],sizeof(PersonTel)); } if (flag) { MessageBox(0,"对不起!!!联系人中没有你要找的人!!!","提示",0); cout <<endl; outData.close(); inData.close(); } else { outData.close(); inData.close(); int i=0; ofstream out("data.dat", ios::out|ios::binary); fstream in("newdata.dat", ios::in|ios::binary); if (!out || !in) { MessageBox(0,"open error!","提示",0); return; } in.read((char*)&Per[i],sizeof(PersonTel)); while (!in.eof()) { out.write((char*)&Per[i],sizeof(PersonTel)); i++; in.read((char*)&Per[i],sizeof(PersonTel)); } out.close(); in.close(); MessageBox(0,"这个人的信息已经从你的通迅录中删除!!!","提示",0); } } /* *函数名称:Menu *功能描述:功能菜单 *输入参数:无 *输出参数:输出选项 *返回值: 无 *其他说明:每次使用一个功能后重新出现菜单以供选择 */ void Menu() //菜单 { cout<<"选项:"<<endl; cout<<"1.添加新的联系人"<<endl; cout<<"2.修改联系人信息"<<endl; cout<<"3.显示所有联系人"<<endl; cout<<"4.查询联系人信息"<<endl; cout<<"5.删除联系人 "<<endl; cout<<"0.退出"<<endl; }
《手机通讯录》之main.cpp
#include <iostream> //C++标准头文件 #include <fstream> //操作文件的头文件 #include <cstdlib> //exit()必要的头文件 #include <windows.h> //清屏函数必要的头文件 #include <shlobj.h> //MessageBox必要的头文件 #include <cstring> #include <iomanip> #include "Telphone.h" void Menu(); int main() { int n; Person per; //建立一个Person对象 do { Sleep(500); //等待500毫秒 Menu(); cout<<"请输入操作指令:"; cin>>n; if (n==0) break; switch (n) { case 1: per.Establish(); //新建联系人 Sleep(1000); system("cls"); //清屏 continue; case 2: per.Modification(); //修改联系人信息 Sleep(1000); system("cls"); continue; case 3: per.Display(); //显示联系人列表 continue; case 4: per.Query(); //查询联系人 Sleep(1000); continue; case 5: per.Delete(); //删除联系人 Sleep(1000); system("cls"); continue; } } while (1); return 0; }
初始界面:
新建联系人功能
新建功能电话号码重复报错
显示全部联系人功能:
修改联系人信息功能
删除联系人功能
删除之后再显示所有联系人
学习心得:
这个项目设计做得自我感觉有些水,,,因为主题太简单了,但是过程还是挺复杂的,断断续续的准备了我差不多快一个月的时间,遇到了很多问题并没有及时解决,这几天有个地实训成功改掉了不少BUG。具体的学习心得就不在这说了,写到报告里去,贺老看在浓浓师生情的份上给个满分如何。
相关文章推荐
- Linux_目录管理命令
- hdu 4308 Saving Princess claire(BFS)
- Partition(hdu4651)2013 Multi-University Training Contest 5----(整数拆分一)
- Jquery图片轮播
- 第九章:样式模块
- 今天是我的生日。
- Unable to open log device ‘/dev/log/main’: No such file or directory
- Android依赖注入:Dagger(Part 3)
- 解决Windows 7删除执行过的 EXE、Bat文件有延迟的问题
- [CortexM0-stm32f0308]reset介绍
- IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)
- 内存检测及C代码解释
- XPath
- c++构造函数详解
- des加密
- 病毒分析报告-样本MD5:7BF49CD89EAEF7FBAD1151D2B1BD9126
- C语言sizeof
- [CortexM0--stm32f0308]discovery开发板
- (一) Qt Model/View 的简单说明
- cug1181