P.1命令行通讯录
命令行通讯录:
1、功能:添加联系人(姓名/电话号码(9位数)/邮箱)、移除、查询、修改、显示所有联系人、保存到本地文本文件/从文件加载
2、训练重点:结构体/类的封装、vector存储自定义对象、map<string, 结构体>快速查询、文件流(fstream)的读写、函数分模块实现(增删改查各写一个函数)
#include <iostream>
#include <string>
#include <unordered_map>
#include <fstream>
#include <stdexcept>
#include <limits>
using namespace std;
class AddressBook {
private:
struct Contact {
string phone;
string email;
Contact() = default;
Contact(string p, string e) : phone(std::move(p)), email(std::move(e)) {}
};
unordered_map<string, Contact> contacts;
const string filename = "contacts.txt";
// 私有辅助函数:清屏
void clearScreen() const {
system("cls||clear");
}
// 私有辅助函数:暂停
void pause() const {
system("pause");
}
public:
// 添加联系人
void addContact(const string &name, const string &phone, const string &email) {
if (contacts.count(name)) {
cout << "联系人 " << name << " 已存在!" << endl;
return;
}
contacts.emplace(name, Contact(phone, email));
cout << "添加成功!" << endl;
}
// 删除联系人
void removeContact(const string &name) {
if (!contacts.count(name)) {
cout << "联系人 " << name << " 不存在!" << endl;
return;
}
contacts.erase(name);
cout << "删除成功!" << endl;
}
// 查询联系人
void searchContact(const string &name) const {
auto it = contacts.find(name);
if (it == contacts.end()) {
cout << "联系人 " << name << " 不存在!" << endl;
return;
}
cout << "姓名:" << name
<< ",电话:" << it->second.phone
<< ",邮箱:" << it->second.email << endl;
}
// 修改联系人
void modifyContact(const string &name) {
auto it = contacts.find(name);
if (it == contacts.end()) {
cout << "联系人 " << name << " 不存在!" << endl;
return;
}
int choice;
cout << "1.修改电话 2.修改邮箱:";
cin >> choice;
if (choice == 1) {
string newPhone;
cout << "新电话:";
cin >> newPhone;
it->second.phone = newPhone;
} else if (choice == 2) {
string newEmail;
cout << "新邮箱:";
cin >> newEmail;
it->second.email = newEmail;
} else {
cout << "无效选择!" << endl;
return;
}
cout << "修改成功!" << endl;
}
// 显示所有联系人
void showAll() const {
if (contacts.empty()) {
cout << "通讯录为空!" << endl;
return;
}
int i = 1;
for (const auto &[name, info] : contacts) { // C++17结构化绑定
cout << i++ << ". 姓名:" << name
<< ",电话:" << info.phone
<< ",邮箱:" << info.email << endl;
}
}
// 保存到文件
void saveToFile() const {
ofstream ofs(filename, ios::out);
if (!ofs) {
cerr << "文件打开失败!" << endl;
return;
}
for (const auto &[name, info] : contacts) {
ofs << name << "," << info.phone << "," << info.email << "\n";
}
ofs.close();
cout << "保存成功!" << endl;
}
// 从文件加载
void loadFromFile() {
ifstream ifs(filename, ios::in);
if (!ifs) {
cerr << "文件打开失败!" << endl;
return;
}
contacts.clear();
string line;
while (getline(ifs, line)) {
size_t p1 = line.find(',');
size_t p2 = line.find(',', p1+1);
if (p1 == string::npos || p2 == string::npos) continue;
string name = line.substr(0, p1);
string phone = line.substr(p1+1, p2-p1-1);
string email = line.substr(p2+1);
contacts.emplace(name, Contact(phone, email));
}
ifs.close();
cout << "加载成功!" << endl;
}
// 菜单界面
void showMenu() {
while (true) {
clearScreen();
cout << "===== 通讯录 =====" << endl;
cout << "1.添加 2.删除 3.查询" << endl;
cout << "4.修改 5.显示 6.保存" << endl;
cout << "7.加载 8.退出" << endl;
cout << "==================" << endl;
cout << "请选择:";
int choice;
if (!(cin >> choice)) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "输入无效!" << endl;
pause();
continue;
}
cout << endl;
string name, phone, email;
switch (choice) {
case 1:
cout << "姓名:"; cin >> name;
cout << "电话:"; cin >> phone;
cout << "邮箱:"; cin >> email;
addContact(name, phone, email); break;
case 2:
cout << "姓名:"; cin >> name;
removeContact(name); break;
case 3:
cout << "姓名:"; cin >> name;
searchContact(name); break;
case 4:
cout << "姓名:"; cin >> name;
modifyContact(name); break;
case 5:
showAll(); break;
case 6:
saveToFile(); break;
case 7:
loadFromFile(); break;
case 8:
cout << "退出成功!" << endl;
return;
default:
cout << "无效选择!" << endl;
}
pause();
}
}
};
int main()
{
AddressBook myAddressBook;
myAddressBook.showMenu();
return 0;
}
Attention:代码可能有更简洁更高效的写法,此处只是分享本人的学习过程。如果你有好的建议或意见,欢迎在评论区分享,我都会看的并且会一一答复☆: .。. o(≧▽≦)o .。.:☆
浙公网安备 33010602011771号