前言
最近完成了西安石油大学C++程序设计的课程设计------通讯录管理系统。这个项目虽然基础,但非常考验对C++面向对象编程(封装、继承、多态)、文件读写以及基本数据结构的掌握。本文将分享我的完整代码、设计思路以及在踩过的坑,希望能帮到后续做这个课设的同学们!👍
开发环境: VS Studio Code
编程语言: C++11
一、 需求分析 & 功能设计
根据课设要求,通讯录系统主要需要实现以下几个核心模块:
- 联系人管理:增加、删除、修改、查找联系人。
- 通讯录管理:显示所有联系人、清空通讯录。
- 数据持久化:将通讯录数据保存到本地文件,下次打开自动加载。
- 交互界面:控制台清屏、菜单交互、退出系统。
二、 系统架构设计
为了体现C++的面向对象特性(OOP) ,我没有把所有代码都塞进main.cpp,而是采用了多文件架构设计:
| 文件名 | 职责 |
|---|---|
contact.h / contact.cpp |
联系人类:封装单个联系人的属性(姓名、电话、地址等)及操作。 |
address.h / address.cpp |
通讯录类:管理联系人的集合,实现增删改查及文件读写逻辑。 |
main.cpp |
主程序:菜单显示、用户交互、业务逻辑调度。 |
类图设计思路:
Contact类作为基类/基础实体类,保存单个联系人的数据。AddressBook类组合了Contact类(或者使用STL容器如vector<Contact>管理),负责统筹调度。
三、 主程序设计与实现 (main.cpp)
主程序是整个通讯录的调度中心,主要负责界面展示、用户交互和业务逻辑路由 。通过 do-while 循环配合 switch-case 分支,实现了经典的控制台交互式菜单。
main.cpp
cpp
#include "address.h"
#include <iostream>
#include <windows.h>
#include <sstream>
#include <fstream>
using namespace std;
int main()
{
Caddress addressBook; // 创建通讯录对象
addressBook.load(); // 打开文件
int choice;
do
{
cout << "通讯录管理系统" << endl;
cout << "1. 添加联系人" << endl;
cout << "2. 删除联系人" << endl;
cout << "3. 查找联系人" << endl;
cout << "4. 修改联系人信息" << endl;
cout << "5. 显示所有联系人" << endl;
cout << "0. 退出(自动保存)" << endl;
cout << "请输入您的选择: ";
cin >> choice;
string name, phone, email;
switch (choice)
{
case 1:
{ // 添加联系人
cout << "请输入姓名: ";
cin >> name;
cout << "请输入电话: ";
cin >> phone;
cout << "请输入学号: ";
cin >> email;
addressBook.add(name, phone, email);
cout << "按任意键继续..." << endl;
cin.ignore();
cin.get();
system("cls");
break;
}
case 2:
{ // 删除联系人
cout << "请输入要删除的联系人姓名: ";
cin >> name;
addressBook.delete1(name);
cout << "按任意键继续..." << endl;
cin.ignore();
cin.get();
system("cls");
break;
}
case 3:
{ // 查找联系人
cout << "请输入要查找的联系人姓名: ";
cin >> name;
addressBook.search(name);
cout << "按任意键继续..." << endl;
cin.ignore();
cin.get();
system("cls");
break;
}
case 4:
{ // 修改联系人
cout << "请输入要修改的联系人姓名: ";
cin >> name;
addressBook.revise(name);
cout << "按任意键继续..." << endl;
cin.ignore();
cin.get();
system("cls");
break;
}
case 5:
{ // 显示所有联系人
addressBook.display();
cout << "按任意键继续..." << endl;
cin.ignore();
cin.get();
system("cls");
break;
}
case 0:
{ // 退出
cout << "退出程序。" << endl;
addressBook.save();
break;
}
default:
cout << "无效的选择,请重新输入!" << endl;
}
} while (choice != 0);
return 0;
}
address.cpp
cpp
#include "address.h"
#include <iostream>
#include <fstream>
#include <algorithm>
#include <sstream>
using namespace std;
// 增加联系人
void Caddress::add(const string &name, const string &phone, const string &id)
{
contacts.emplace_back(name, phone, id);
cout << "添加成功" << endl;
}
// 删除联系人
void Caddress::delete1(const std::string &name)
{
for (auto it = contacts.begin(); it != contacts.end(); ++it)
{
if (it->getName() == name)
{
contacts.erase(it);
std::cout << "联系人删除成功!" << std::endl;
return;
}
}
std::cout << "未找到联系人!" << std::endl;
}
// 查找联系人
void Caddress::search(const std::string &name)
{
for (const auto &contact : contacts)
{
if (contact.getName() == name)
{
std::cout << "找到联系人:" << std::endl;
contact.display();
return;
}
}
std::cout << "未找到联系人!" << std::endl;
}
// 修改联系人信息
void Caddress::revise(const std::string &name)
{
for (auto &contact : contacts) // 使用引用以便修改
{
if (contact.getName() == name)
{
std::cout << "找到联系人,当前信息:" << std::endl;
contact.display();
std::string newPhone, newId;
std::cout << "请输入新的电话号码(直接回车保持不变):";
std::getline(std::cin, newPhone);
if (!newPhone.empty())
{
contact.setPhone(newPhone);
}
std::cout << "请输入新的学号(直接回车保持不变):";
std::getline(std::cin, newId);
if (!newId.empty())
{
contact.setId(newId);
}
std::cout << "修改成功!更新后的信息:" << std::endl;
contact.display();
return;
}
}
std::cout << "未找到联系人!" << std::endl;
}
// 显示所有联系人
void Caddress::display()
{
if (contacts.empty())
{
std::cout << "通讯录为空!" << std::endl;
return;
}
std::cout << "通讯录中的联系人信息:" << std::endl;
for (const auto &contact : contacts)
{
contact.display();
std::cout << "---------------------" << std::endl;
}
}
// 保存联系人到文件
void Caddress::save()
{
std::ofstream file("data.txt");
for (const auto &contact : contacts)
{
file << contact.getName() << "," << contact.getPhone() << "," << contact.getId() << std::endl;
}
file.close();
}
void Caddress::load(){
ifstream inFile("data.txt");
if (inFile){
string name, phone, id, all;
while (getline(inFile, all)){
stringstream ss(all);
if (getline(ss, name, ',') && getline(ss, phone, ',')
&& getline(ss, id)){
// 读取每一行的姓名、电话和学号
contacts.emplace_back(name, phone, id);
}
}
inFile.close();
}
}
address.h
cpp
#ifndef ADDRESSBOOK_H
#define ADDRESSBOOK_H
#include <vector>
#include <string>
#include "contact.h"
class Caddress
{
private:
std::vector<Ccontact> contacts; // 存储联系人的容器
public:
void add(const std::string &name, const std::string &phone, const std::string &id);
void delete1(const std::string &name);
void search(const std::string &name);
void revise(const std::string &name);
void display();
void save();
void load();
// 提供一个方法返回容器的引用以便遍历
const std::vector<Ccontact>& getContacts() const {
return contacts;
}
};
#endif // ADDRESSBOOK_H
contact.h
cpp
#ifndef ADDRESSBOOK_H
#define ADDRESSBOOK_H
#include <vector>
#include <string>
#include "contact.h"
class Caddress
{
private:
std::vector<Ccontact> contacts; // 存储联系人的容器
public:
void add(const std::string &name, const std::string &phone, const std::string &id);
void delete1(const std::string &name);
void search(const std::string &name);
void revise(const std::string &name);
void display();
void save();
void load();
// 提供一个方法返回容器的引用以便遍历
const std::vector<Ccontact>& getContacts() const {
return contacts;
}
};
#endif // ADDRESSBOOK_H
contact.cpp
cpp
#include "contact.h"
#include <iostream>
std::string Ccontact::getName() const
{
return name;
}
std::string Ccontact::getPhone() const
{
return phone;
}
std::string Ccontact::getId() const
{
return id;
}
void Ccontact::display() const
{
std::cout << "姓名: " << name << "\t";
std::cout << "电话: " << phone << "\t";
std::cout << "学号: " << id << std::endl;
}