📄 dianhuaben.cpp
字号:
/*电话簿管理—源代码及关键源代码注解如下*/
#include<fstream.h>
#include<conio.h>
#include<iostream.h>
#include<iomanip.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
class CTelRecord //定义电话簿记录类
{private:
int nYear,nMonth,nDay,nHour,nMinute; //时间单元
char Name[20]; //电话簿的数据,姓名
char Homenum[20]; //电话号码
public:
CTelRecord();
CTelRecord(char *name,char *homenum); //构造函数
void SetRecord(char * name,char *homenum); //输入数据函数
int Compare(CTelRecord &); //比较函数,比较姓名
void Show(); //打印数据函数
void Modify(char *homenum); //修改结点上的数据
int LookChar(char *letter); //根据首字母查找匹配的姓名
char * GetName(){return Name;} //返回姓名
};
class CNode //定义结点类
{
private:
CTelRecord * pData; //用于指向数据类的指针
CNode * pNext; //指向链表下一结点的指针
public:
CNode(){ pData=0;pNext=0;} //结点构造函数
CNode(CNode &node) //用于拷贝的构造函数
{
pData=node.pData;
pNext=node.pNext;
}
void InputData(CTelRecord *pdata){ pData=pdata; } //输入数据
void ShowNode(){ pData->Show(); }
CTelRecord * GetData(){ return pData;}
friend class CList; //定义链表类为友元类
};
class CList //定义链表类
{
private:
CNode * pHead; //链表头结点指针
public:
CList(){ pHead=0; }
~CList(){ DeleteList(); }
void AddNode(CNode * pnode); //首部添加结点
CNode * DeleteNode(CNode *); //删除一个指定的结点,返回该结点的指针
CNode * LookUp(CTelRecord &); /*查找一个指定的数据,返回该数据所在结点在链表中的指针,若未找
到返回0 */
void ShowList(); //打印整个链表
void DeleteList(); //删除整个链表
CNode * GetListHead(){return pHead;} //返回链表首结点
CNode * GetListNextNode(CNode *); //返回链表指定结点的下一个结点
void Insert(CNode * pnode); //按姓名插入一个结点
};
inline istream & Flush(istream & stream) //清空输入缓冲区
{
stream.clear();
int chars_to_skip=stream.rdbuf()->in_avail();
return stream.ignore(chars_to_skip);
}
void main()
{
int choice;
CList list;
CTelRecord *p;
CNode *pn;
char name[20]; //用于输入姓名
char homenum[20]; //用于输入家庭电话
char str[20];
ifstream infile("FRIENDS.DAT",ios::in|ios::nocreate); //从文件中读入链表
if(!infile)
{
cout<<"欢迎使用电话簿管理程序.\n"<<flush;
system("pause");
system("cls");
}
else
{
CTelRecord pitem;
infile.read(reinterpret_cast<char *>(&pitem),sizeof(CTelRecord));
while(! infile.eof())
{
p=new CTelRecord;
*p=pitem;
pn=new CNode;
pn->InputData(p);
list.Insert(pn); //将结点插入链表
infile.read(reinterpret_cast<char *>(&pitem),sizeof(CTelRecord));
}
}
infile.close(); //关闭输入文件
do
{
cout<<"\n 欢迎进入电话簿管理系统 "<<endl<<endl;
cout<<" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
cout<<"\n\n 1. 添加电话簿记录 "
<<"\n\n 2. 显示电话簿记录 "
<<"\n\n 3. 根据姓名查询电话簿数据"
<<"\n\n 4. 根据姓名删除电话簿数据"
<<"\n\n 5. 根据姓名修改电话簿数据"
<<"\n\n 6. 智能查找电话簿数据 "
<<"\n\n 0. 退出系统 "<<endl<<endl;
cout<<" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl<<endl;
cout<<" 0610200256 张佳斌";
cout<<"\n\n输入选择: "<<endl;
Flush(cin);
cin.getline(str,20);
choice=atoi(str);
switch(choice)
{
case 1: //添加电话簿记录
system("cls");
cout<<"输入姓名(拼音):";
Flush(cin);
cin.getline(name,20); //获取姓名数据
cout<<endl;
cout<<"输入家庭电话:";
Flush(cin);
cin.getline(homenum,20); //获取家庭电话数据
cout<<endl;
p=new CTelRecord(name,homenum); //开辟电话簿记录类新空间
pn=new CNode; //开辟结点类新空间
pn->InputData(p); // 结点数据输入函数
list.Insert(pn); //结点数据插入链表
system("cls");
break;
case 2: //显示电话簿记录
system("cls"); //清空屏幕
pn=list.GetListHead();
if(pn==0) //结点数据为空时
{
cout<<"无电话簿数据."<<endl;
system("pause");
system("cls");
}
else //输出结点数据
{
list.ShowList();
system("pause");
system("cls");
}
break;
case 3: //根据姓名查询电话簿数据
system("cls"); //清空屏幕
cout<<"输入姓名(拼音):";
Flush(cin);
cin.getline(name,20); //获取姓名
p=new CTelRecord(name,homenum); //开辟电话簿记录类新空间
pn=list.LookUp(*p); //查找数据函数
if(pn) //结点数据不为空则输出结点数据,为空则输出无电话簿记录
{
pn->GetData()->Show();
system("pause");
system("cls");
}
else
{
cout<<"\n无电话簿数据 \n\n"<<flush; //结点数据为空输出无电话簿数据
system("pause");
system("cls");
}
delete p;
break;
case 4: //根据姓名删除电话簿记录
system("cls");
cout<<"输入姓名(拼音):";
Flush(cin);
cin.getline(name,20);
cout<<endl;
p=new CTelRecord(name,homenum);
pn=list.LookUp(*p);
if(pn)
{
char YesNo;
cout<<"找到电话簿数据,确定删除(y/n):"; //用户选择是否删除
cin>>YesNo;
if(YesNo=='y'||YesNo=='Y') list.DeleteNode(pn);
system("cls"); //清空屏幕
}
else
{
cout<<"\n无电话簿数据 \n\n"<<flush; //若无数据,则输出无电话簿数据
system("pause");
system("cls");
}
delete p;
break;
case 5: //根据姓名修改电话簿数据
system("cls");
cout<<"输入姓名(拼音):";
Flush(cin);
cin.getline(name,20);
p=new CTelRecord(name,homenum);
pn=list.LookUp(*p);
if(pn) pn->GetData()->Show();
else
{
cout<<"\n无电话簿数据 \n\n"<<flush;
system("pause");
system("cls");
break;
}
cout<<"\n\n1. 只修改电话号码"; //选择只修改电话号码
cout<<"\n\n2. 修改电话号码和姓名 "; //选择电话号码和姓名均更改
cout<<"\n\n输入选择: ";
cin>>choice;
switch(choice)
{case 1:
cout<<"输入电话号码:";
Flush(cin);
cin.getline(homenum,20);
cout<<endl;
pn->GetData()->Modify(homenum); //修改结点数据
break;
case 2: //可修改结点上的所有数据
list.DeleteNode(pn);
cout<<"输入姓名(拼音):";
Flush(cin);
cin.getline(name,20); //修改姓名
cout<<endl;
cout<<"输入电话号码:";
Flush(cin);
cin.getline(homenum,20); //修改家庭电话
cout<<endl;
p=new CTelRecord(name,homenum);//新的电话簿记录类
pn=new CNode; //新结点类
pn->InputData(p);
list.Insert(pn);
break;
default:
cout<<"输入错误\n";
break;
}
delete p;
system("cls");
break;
case 6: //智能查找
system("cls");
Flush(cin);
cout<<"输入姓的首字母:";
cin.getline(name,20);
pn=list.GetListHead(); //提取链表首结点
while(pn)
{
p=pn->GetData();
if(p->LookChar(name)==1)
p->Show();
pn=list.GetListNextNode(pn);
}
system("pause");
system("cls");
break;
case 0:
break;
default:
cout<<"选择错误!\n"<<flush;
system("pause");
system("cls");
}
}while(choice!=0);
ofstream outfile("FRIENDS.DAT"); //从链表中写入文件
if(!outfile)
{
cout<<"错误,不能打开文件";
getch();
exit(1);
}
pn=list.GetListHead();
while(pn)
{
p=pn->GetData();
outfile.write(reinterpret_cast<const char *>(p),sizeof(CTelRecord));
pn=list.GetListNextNode(pn);
}
outfile.close();
}
CTelRecord::CTelRecord() //数据初始化
{
strcpy(Name,"\0");
strcpy(Homenum,"\0");
time_t time_date; //时间转换
tm CurrentTime;
time_date=time(NULL);
CurrentTime=*localtime(& time_date);
nYear=CurrentTime.tm_year+1900;
nMonth=CurrentTime.tm_mon+1;
nDay=CurrentTime.tm_mday;
nHour=CurrentTime.tm_hour;
nMinute=CurrentTime.tm_min;
}
CTelRecord::CTelRecord(char * name,char * homenum) //结点数据赋值
{
strcpy(Name,name);
strcpy(Homenum,homenum);
time_t time_date;
tm CurrentTime;
time_date=time(NULL); //写入时间
CurrentTime=*localtime(& time_date);
nYear=CurrentTime.tm_year+1900;
nMonth=CurrentTime.tm_mon+1;
nDay=CurrentTime.tm_mday;
nHour=CurrentTime.tm_hour;
nMinute=CurrentTime.tm_min;
}
void CTelRecord::SetRecord(char * name,char * homenum) //修改结点数据
{
strcpy(Name,name);
strcpy(Homenum,homenum);
}
int CTelRecord::Compare(CTelRecord & pitem) //比较函数,比较姓名,
{
int n;
n=strcmp(Name,pitem.Name);
if(n!=0) return 0;
else return 1;
}
void CTelRecord::Show() //输出数据
{
cout<<"姓名: "<<Name<<endl; //输出姓名
cout <<"家庭电话: "<<Homenum<<endl; //输出电话号码
cout<<"时间:"<<nYear<<"-"<<nMonth<<"-"<<nDay<<" "
<<nHour<<":"<<nMinute<<endl; //存储时间的输出
cout<<endl;
}
void CTelRecord::Modify(char * homenum) //修改结点上的电话号码
{
strcpy(Homenum,homenum); //修改电话号码
}
int CTelRecord::LookChar(char * letter) //首字母匹配返回1,否则返回0
{
if(Name[0]==letter[0])
return 1;
return 0;
}
void CList::AddNode(CNode *pnode) //添加结点
{
if(pHead==0)
{
pHead=pnode;
pnode->pNext=0;
}
else
{
pnode->pNext=pHead;
pHead=pnode;
}
}
CNode * CList::DeleteNode(CNode *pnode) //删除一个指定的结点,返回该结点的指针
{
if(pnode==pHead)
{
pHead=pnode->pNext;
pnode->pNext=0;
}
else
{
CNode *p=pHead;
while(p->pNext!=pnode)
p=p->pNext;
p->pNext=pnode->pNext;
pnode->pNext=0;
}
return(pnode);
}
CNode * CList::LookUp(CTelRecord &pitem)/*查找一个指定的数据,返回该数据所在结点
在链表中的指针,若未找到返回0 */
{
CNode * pn=pHead;
while(pn)
{
if(pn->pData->Compare(pitem)) return pn;
pn=pn->pNext;
}
return 0;
}
void CList::ShowList() //打印整个链表
{
CNode * p=pHead;
while(p)
{
p->pData->Show();
p=p->pNext;
}
}
void CList::DeleteList() //删除整个链表
{
CNode * p,* q;
p=pHead;
while(p)
{
delete p->pData;
q=p;
p=p->pNext;
delete q;
}
}
CNode * CList::GetListNextNode(CNode *pnode) //返回链表指定结点的下一个结点
{
return pnode->pNext;
}
void CList::Insert(CNode * pnode) //根据姓名的顺序插入链表
{
CNode * p1,* p2;
if(pHead==0)
{
pHead=pnode;
pnode->pNext=0;
return;
}
if(strcmp(pHead->pData->GetName(),pnode->pData->GetName())>=0)
{
pnode->pNext=pHead;
pHead=pnode;
return;
}
p2=p1=pHead;
while(p2->pNext&&strcmp(p2->pData->GetName(),pnode->pData->GetName())<0)
{
p1=p2;
p2=p2->pNext;
}
if(strcmp(p2->pData->GetName(),pnode->pData->GetName())<0)
{
p2->pNext=pnode;
pnode->pNext=0;
}
else
{
pnode->pNext=p2;
p1->pNext=pnode;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -