2020-0908
通常学习C++我们都会学习一些设计模式,
最早我想利用设计模式对此通讯录进行改写,以便增强可维护性和满足开闭原则
被老师拒绝了,毕竟此代码量不高,1000行以内 确实没必要。
此项目其实最能挖掘的点应该是 “动态数组” ,STL库其实有这一概念,不过我就不多说了。
2020-0806
这并不是一个完整的项目,个人感觉还需要QT界面等等。
#include
#include "Contact.h"
using namespace std;
int main(void)
{
funcClass user;
int choice = 0;
while (true)
{
user.funcMenu();
cout << "请输入您的选择:\n";
cin >> choice;
switch (choice)
{
case 0: // 0.退出通讯录
user.funcExit();
break;
case 1: // 1.添加联系人
user.addContacts();
break;
case 2: // 2.删除联系人
user.DelContacts();
break;
case 3: // 3.修改联系人
user.modContacts();
break;
case 4: // 4.查找联系人
user.findContacts();
break;
case 5: // 5.显示联系人
user.showContacts();
break;
case 6: // 6.排序联系人
user.sortContacts();
case 7: // 7.清空联系人
user.cleanFile();
break;
default:
system("cls");
break;
}
}
return 0;
}
#pragma once //防止头文件重复
#include
#include
using namespace std;
class Contacts
{
public:
virtual void showInfo() = 0;//显示联系人信息
string name; //同学姓名
string addr; //家庭住址
string phone; //联系电话
string workfor; //工作单位
};
class newContacts :public Contacts
{
public:
//构造函数 传入的信息,需传四个
newContacts(string name, string addr, string phone, string workfor);
void showInfo(); //重写 显示个人信息(不加virtual也可以)
};
// 功能实现类
class funcClass
{
public:
funcClass();
int m_num; //记录通讯录人数
Contacts** m_cttArray; //通讯录 数组指针
bool m_fileIsEmpty; //判断文件是否为空 标志
void funcMenu(); // 展示功能菜单函数
void funcExit(); // 退出通讯录系统
void addContacts(); // 添加联系人
void fileSave(); //文件保存
int getNum(); //统计文件中人数
void init(); //初始化
void showContacts(); //显示联系人
void DelContacts(); //删除联系人
int IsExit(string name);//判断联系人是否存在 存在返回在数组中的位置,不存在返回-1
void modContacts(); //修改联系人信息
void findContacts(); //按已有信息查找
void sortContacts(); //按照姓名排序
void cleanFile(); //清空文件
~funcClass();
};
#include
#include
#include
#include "Contact.h"
using namespace std;
#define FILENAME "phone.txt"
//构造函数 传入的信息,需传四个
newContacts::newContacts(string name, string addr, string phone, string workfor)
{
this->name = name;
this->addr = addr;
this->phone = phone;
this->workfor = workfor;
}
// 显示个人信息
void newContacts::showInfo()
{
cout << "同学姓名:" << this->name
<< "\t家庭住址:" << this->addr
<< "\t联系电话:" << this->phone
<< "\t工作单位:" << this->workfor << endl;
}
funcClass::funcClass()
{
//1.文件不存在
ifstream fi;
fi.open(FILENAME, ios::in); //读文件
if (!fi.is_open())
{ //初始化属性
//初始化记录人数
this->m_num = 0;
//初始化数组指针
this->m_cttArray = nullptr;
//初始化文件是否为空
this->m_fileIsEmpty = true;
fi.close();
return;
}
//2.文件存在但数据为空
char ch;
fi >> ch;
if (fi.eof())
{
//初始化记录人数
this->m_num = 0;
//初始化数组指针
this->m_cttArray = nullptr;
//初始化文件是否为空
this->m_fileIsEmpty = true;
fi.close();
return;
}
//3.当文件存在,且保存联系人数据
int num = this->getNum();
this->m_num = num;
//开辟空间
this->m_cttArray = new Contacts * [this->m_num];
//将文件中的数据,存到数组中
this->init();
}
// 展示功能菜单函数
void funcClass::funcMenu()
{
cout << "0.退出通讯录\n";
cout << "1.添加联系人\n";
cout << "2.删除联系人\n";
cout << "3.修改联系人\n";
cout << "4.查找联系人\n";
cout << "5.显示联系人\n";
cout << "6.排序联系人\n";
cout << "7.清空联系人\n";
}
// 退出通讯录系统
void funcClass::funcExit()
{
cout << "欢迎下次使用!\n";
system("pause"); // 按键退出
exit(0); // 退出程序
}
void funcClass::addContacts()
{
cout << "请输入添加联系人数量:\n";
int addNum = 0; //保存用户的输入数量
cin >> addNum;
if (addNum > 0)
{
//添加
//计算添加新空间大小
int newSize = this->m_num + addNum; //新空间人数 = 原来记录人数+新增人数
//开辟新空间
Contacts ** newSpace = new Contacts* [newSize];
//将原来空间下的数据,拷贝到新空间下
if (this->m_cttArray != nullptr)
{
for (int i = 0; i < this->m_num; i++)
{
newSpace[i] = this->m_cttArray[i];
}
}
//批量添加新数据
for (int i = 0; i < addNum; i++)
{
string name; //同学姓名
string addr; //家庭住址
string phone; //联系电话
string workfor; //工作单位
cout << "请输入第" << i + 1 << "个同学的姓名" << endl;
cin >> name;
cout << "请输入第" << i + 1 << "个同学的家庭住址" << endl;
cin >> addr;
cout << "请输入第" << i + 1 << "个同学的联系电话" << endl;
cin >> phone;
cout << "请输入第" << i + 1 << "个同学的工作单位" << endl;
cin >> workfor;
Contacts* contact = new newContacts(name, addr, phone, workfor);
//创建联系人,保存到数组中
newSpace[this->m_num + i] = contact;
}
//释放原有空间
delete[]this->m_cttArray;
//更改新空间指向
this->m_cttArray = newSpace;
//更新 通讯录人数
this->m_num = newSize;
//更新 部位空标识符
this->m_fileIsEmpty = false;
//提示添加成功
cout << "成功添加" << addNum << "名新的同学" << endl;
//保存数据到文件中
this->fileSave();
}
else
{
cout << "您的输入有误,请重新输入\n";
}
//按任意键后 清屏回到上级目录
system("pause");
system("cls");
}
// 文件保存
void funcClass::fileSave()
{
ofstream fo;
fo.open(FILENAME, ios::out);//用输出的方式打开文件 -- 写文件
//将每个人的数据写入到文件中
for (int i = 0; i < this->m_num; i++)
{
fo << this->m_cttArray[i]->name << " "
<< this->m_cttArray[i]->addr << " "
<< this->m_cttArray[i]->phone << " "
<< this->m_cttArray[i]->workfor << endl;
}
// 关闭文件
fo.close();
}
//统计文件中人数:
int funcClass::getNum()
{
ifstream fi;
fi.open(FILENAME, ios::in);//打开文件 读
string name;
string addr;
string phone;
string workfor;
int num = 0;
while (fi >> name && fi >> addr && fi >> phone && fi >> workfor)
{
//统计人数变量
num++;
}
return num;
}
// 初始化
void funcClass::init()
{
ifstream fi;
fi.open(FILENAME, ios::in);
string name;
string addr;
string phone;
string workfor;
int index = 0;
while (fi >> name && fi >> addr && fi >> phone && fi >> workfor)
{
Contacts* contact = new newContacts(name, addr, phone, workfor);
this->m_cttArray[index] = contact;
index++;
}
//关闭文件
fi.close();
}
// 显示通讯录信息
void funcClass::showContacts()
{
//判断文件是否为空
if (this->m_fileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
}
else
{
for (int i = 0; i < m_num; i++)
{
//利用多态调用程序接口
this->m_cttArray[i]->showInfo();
}
}
//按任意键后清屏
system("pause");
system("cls");
}
//删除联系人
void funcClass::DelContacts()
{
if (this->m_fileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
}
else
{
//按照联系人姓名删除
cout << "请输入想要删除联系人姓名: " << endl;
string name;
cin >> name;
int index = this->IsExit(name);
if (index != -1)//说明联系人存在,并且要删除index位置的联系人
{
//数据前移
for (int i = index; i < this->m_num - 1; i++)
{
this->m_cttArray[i] = this->m_cttArray[i + 1];
}
this->m_num--;//更新数组中记录人员个数
this->fileSave();
cout << "删除成功!" << endl;
}
else
{
cout << "删除失败,未找到该联系人" << endl;
}
}
//按任意键 清屏
system("pause");
system("cls");
}
//判断联系人是否存在 存在返回在数组中的位置,不存在返回-1
int funcClass::IsExit(string name)
{
int index = -1;
for (int i = 0; i < this->m_num; i++)
{
if (this->m_cttArray[i]->name == name)
{
//找到该联系人
index = i;
break;
}
}
return index;
}
//修改联系人信息
void funcClass::modContacts()
{
if (this->m_fileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
}
else
{
cout << "请输入修改联系人的姓名: " << endl;
string name;
cin >> name;
int ret = this->IsExit(name);
if (ret != -1)
{
//查找到 姓名存在 的 联系人
delete this->m_cttArray[ret];
string newName = nullptr;//新的同学姓名
string newAddr = nullptr;//新的家庭住址
string newPhone = nullptr;//新的联系电话
string newWorkfor = nullptr;//新的工作单位
cout << "查找到姓名为 " << name << " 的联系人,请输入新的姓名: " << endl;
cin >> newName;
cout << "请输入新的家庭地址:" << endl;
cin >> newAddr;
cout << "请输入新的联系电话:" << endl;
cin >> newPhone;
cout << "请输入新的工作单位:" << endl;
cin >> newWorkfor;
Contacts* contact = new newContacts(newName, newAddr, newPhone, newWorkfor);
//更新数据 到数组中
this->m_cttArray[ret] = contact;
cout << "修改成功!" << endl;
//保存文件中
this->fileSave();
}
else
{
cout << "查无此人,修改失败!" << endl;
}
}
system("pause");
system("cls");
}
//查找联系人
void funcClass::findContacts()
{
if (this->m_fileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
}
else
{
cout << "请输入查找的方式:" << endl;
cout << "1.按同学姓名查找 " << endl;
cout << "2.按家庭住址查找 " << endl;
cout << "3.按联系电话查找 " << endl;
cout << "4.按工作单位查找 " << endl;
int select = 0;
cin >> select;
if (select == 1)
{
string newName;
cout << "请输入查找的同学姓名:" << endl;
cin >> newName;
//加入判断是否查到的标志
bool flag = false; //默认未找到该联系人
for (int i = 0; i < m_num; i++)
{
if (this->m_cttArray[i]->name == newName)
{
cout << "查找成功,姓名为 " << newName << " 的同学信息如下:" << endl;
flag = true;
//调用显示信息接口
this->m_cttArray[i]->showInfo();
}
}
if (flag == false)
{
cout << "查找失败,查无此人!" << endl;
}
}
else if (select == 2)
{
string newAddr;
cout << "请输入查找的家庭住址:" << endl;
cin >> newAddr;
//加入判断是否查到的标志
bool flag = false; //默认未找到该联系人
for (int i = 0; i < m_num; i++)
{
if (this->m_cttArray[i]->addr == newAddr)
{
cout << "查找成功,家庭住址为 " << newAddr << " 的同学信息如下:" << endl;
flag = true;
//调用显示信息接口
this->m_cttArray[i]->showInfo();
}
}
if (flag == false)
{
cout << "查找失败,查无此人!" << endl;
}
}
else if (select == 3)
{
string newPhone;
cout << "请输入查找的联系电话:" << endl;
cin >> newPhone;
//加入判断是否查到的标志
bool flag = false; //默认未找到该联系人
for (int i = 0; i < m_num; i++)
{
if (this->m_cttArray[i]->phone == newPhone)
{
cout << "查找成功,联系电话为 " << newPhone << " 的同学信息如下:" << endl;
flag = true;
//调用显示信息接口
this->m_cttArray[i]->showInfo();
}
}
if (flag == false)
{
cout << "查找失败,查无此人!" << endl;
}
}
else if (select == 4)
{
string newWorkfor;
cout << "请输入查找的工作单位:" << endl;
cin >> newWorkfor;
//加入判断是否查到的标志
bool flag = false; //默认未找到该联系人
for (int i = 0; i < m_num; i++)
{
if (this->m_cttArray[i]->workfor == newWorkfor)
{
cout << "查找成功,工作单位为 " << newWorkfor << " 的同学信息如下:" << endl;
flag = true;
//调用显示信息接口
this->m_cttArray[i]->showInfo();
}
}
if (flag == false)
{
cout << "查找失败,查无此人!" << endl;
}
}
else
{
cout << "输入选项有误!" << endl;
}
}
//按任意键清屏
system("pause");
system("cls");
}
//按照姓名排序 算法:选择排序(比较好理解的一种排序)
void funcClass::sortContacts()
{
if (this->m_fileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
//按任意键清屏
system("pause");
system("cls");
}
else
{
cout << "请选择排序方式:" << endl;
cout << "1.按同学姓名进行升序" << endl;
cout << "2.按同学姓名进行降序" << endl;
int select = 0;
cin >> select;
for (int i = 0; i < m_num; i++)
{
int minOrMax = i; //声明最小值 或 最大值 下标
for (int j = i + 1; j < this->m_num; j++)
{
if (select == 1)//升序
{
if (this->m_cttArray[minOrMax]->name > this->m_cttArray[j]->name)
{
minOrMax = j;
}
}
else //降序
{
if (this->m_cttArray[minOrMax]->name < this->m_cttArray[j]->name)
{
minOrMax = j;
}
}
}
//判断一开始认定 最小值或最大值 是不是 计算的最小值或最大值,如果不是 交换
if (i != minOrMax)
{
Contacts* newContact = this->m_cttArray[i];
this->m_cttArray[i] = this->m_cttArray[minOrMax];
this->m_cttArray[minOrMax] = newContact;
}
}
cout << "排序成功!排序后的结果为:" << endl;
this->fileSave(); //排序后结果保存到文件中
this->showContacts(); //展示
}
}
//清空文件
void funcClass::cleanFile()
{
if (this->m_fileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
}
else
{
cout << "确定清空?" << endl;
cout << "1.确定" << endl;
cout << "2.返回" << endl;
int select = 0;
cin >> select;
if (select == 1)
{
//清空文件
ofstream fo(FILENAME, ios::trunc);//删除文件后重新创建
fo.close();
if (this->m_cttArray != nullptr)
{
//删除堆区的 每个 联系人 对象
for (int i = 0; i < this->m_num; i++)
{
delete this->m_cttArray[i];
this->m_cttArray[i] = nullptr;
}
delete[] this->m_cttArray;
this->m_cttArray = nullptr;
this->m_num = 0;
this->m_fileIsEmpty = true;
}
cout << "清空成功!" << endl;
}
}
//按任意键清屏
system("pause");
system("cls");
}
// 析构函数
funcClass::~funcClass()
{
if (this->m_cttArray != nullptr)
{
for (int i = 0; i < this->m_num; i++)
{
if (this->m_cttArray[i] != nullptr)
{
delete this->m_cttArray[i];
}
}
delete[] this->m_cttArray;
this->m_cttArray = nullptr;
}
}
之前用双向链表写过通讯录了,想着单链表写一下,花了点时间敲了敲。
现在回过头来看,还是不予置评吧。
不过没打算删,放这当黑历史。
还是要继续补基础知识。
#include
#include
#include
typedef struct Node
{
char name[100];
char addr[100];
char phone[100];
struct Node* next;
}*Pnode;
typedef struct List
{
Pnode head;//头指针
Pnode tail;//尾指针
}*Plist;
//初始化链表
Plist createList()
{
Plist plist = (Plist)malloc(sizeof(struct List));
if (plist == NULL)
{
printf("申请plist空间失败\n");
return NULL;
}
plist->head = (Pnode)malloc(sizeof(struct Node));
if (plist->head == NULL)
{
printf("申请plist->head空间失败\n");
free(plist);
return NULL;
}
plist->tail = (Pnode)malloc(sizeof(struct Node));
if (plist->head == NULL)
{
printf("申请plist->tail空间失败\n");
free(plist);
return NULL;
}
plist->tail = NULL;
plist->head = NULL;
return plist;
}
//1.添加联系人 功能 //尾插法
void addNode(Plist list)
{
Pnode newNode = (Pnode)malloc(sizeof(struct Node));
if (newNode == NULL)
{
printf("newNode申请空间失败\n");
return;
}
//填充数据域
char name[100], addr[100], phone[100];
printf("输入联系人姓名:");
scanf_s("%s", name, 100);
strcpy_s(newNode->name, 100, name);
printf("输入联系人地址:");
scanf_s("%s", addr, 100);
strcpy_s(newNode->addr, 100, addr);
printf("输入联系人电话号码:");
scanf_s("%s", phone, 100);
strcpy_s(newNode->phone, 100, phone);
//1.空表;2.非空表 两种情况插入
if (list->head == NULL)
{
list->head = newNode;
}
else
{
list->tail->next = newNode;
}
list->tail = newNode;
newNode->next = NULL;
system("cls");
printf("添加联系人成功\n");
}
//获取链表长度
int nodeLen(Plist list)
{
int len = 0;
Pnode newNode = list->head;
while (newNode != NULL)
{
len++;
newNode = newNode->next;
}
return len;
}
//2.显示联系人信息功能
void showNode(Plist list)
{
Pnode newNode = list->head;
while (newNode != NULL)
{
printf("姓名:%s\t地址:%s\t电话号码:%s\n", newNode->name, newNode->addr, newNode->phone);
newNode = newNode->next;
}
}
//通过数据域比较,获取结点地址
Pnode getNode(char name[], Plist newlist)
{
Pnode newNode = newlist->head;
while (strcmp(newNode->name, name) != 0)
{
newNode = newNode->next;
}
return newNode;
}
//遍历获取是第几个链表,返回地址
Pnode getNode2(Plist list, int len)
{
Pnode newNode = list->head;
int num = 1;
while(num!=len)
{
num++;
newNode = newNode->next;
}
return newNode;
}
//不知是第几个链表,返回值为
int getNode3(Plist list, Pnode node)
{
Pnode newNode = list->head;
int len = 1;
while (strcmp(newNode->name,node->name) != 0)
{
len++;
newNode = newNode->next;
}
return len;
}
//删除联系人
void delNode(Plist list)
{
printf("输入您要删除的联系人姓名\n");
char name[100];
scanf_s("%s", name, 100);
Pnode newNode = getNode(name, list);
int len = nodeLen(list);
if (list->head == newNode && len == 1) //删除第一个
{
list->head = newNode->next;
}
else if (list->tail == newNode) //删除最后一个
{
list->tail = getNode2(list, len - 1);
list->tail->next = NULL;
}
else //删除中间某一个
{
int num = getNode3(list, newNode);
Pnode node = getNode2(list, num - 1);
node->next = newNode->next;
}
free(newNode);
system("cls");
printf("删除成功\n");
}
//4.修改联系人信息
void upDate(Plist list)
{
printf("请输入你要修改的联系人姓名:\n");
char name[100];
scanf_s("%s", name, 100);
Pnode newNode = getNode(name, list); //获取该链表
system("cls");
printf("1.修改姓名\n");
printf("2.修改地址\n");
printf("3.修改电话号码\n");
printf("4.返回菜单\n");
int key = 0;
scanf_s("%d", &key);
switch (key)
{
case 1:
system("cls");
printf("请输入新的姓名:\n");
char newname[100];
scanf_s("%s", newname, 100);
strcpy_s(newNode->name,100,newname);
printf("修改成功!");
break;
case 2:
system("cls");
printf("请输入新的地址:\n");
char newaddr[100];
scanf_s("%s", newaddr, 100);
strcpy_s(newNode->addr,100, newaddr);
printf("修改成功!");
break;
case 3:
system("cls");
printf("请输入新的电话号码:\n");
char newphone[100];
scanf_s("%s", newphone, 100);
strcpy_s(newNode->phone,100, newphone);
printf("修改成功!");
case 4:
exit(1);
break;
}
}
void queryNode(Plist list)
{
printf("请输入你要查找的联系人姓名:\n");
char name[100];
scanf_s("%s", name, 100);
Pnode newNode = getNode(name, list); //获取该链表
system("cls");
printf("姓名:%s\t地址:%s\t电话号码:%s\n", newNode->name, newNode->addr, newNode->phone);
}
//菜单显示
void Menu()
{
//1.初始化链表
Plist newlist = createList();
if (NULL == newlist)
{
printf("创建失败\n");
}
while (1)
{
system("cls");
printf("\n1.添加新联系人\n");
printf("2.显示联系人信息\n");
printf("3.删除联系人\n");
printf("4.修改联系人信息\n");
printf("5.查找联系人\n");
printf("6.退出通讯录\n\n");
int key = 0;
scanf_s("%d", &key);
switch (key)
{
case 1:
system("cls"); addNode(newlist); system("pause");
break;
case 2:
system("cls"); showNode(newlist); system("pause");
break;
case 3:
system("cls"); delNode(newlist); system("pause");
break;
case 4:
system("cls"); upDate(newlist); system("pause");
break;
case 5:
system("cls"); queryNode(newlist); system("pause");
break;
case 6:
exit(1);
break;
}
}
}
// 学海无涯苦作舟,书山有路勤为径。 加油!
int main()
{
Menu();
return 0;
}