通信录管理系统--我的第一个C++小程序(源码可用)

java转c++的第三天,写完了人生中的第一个c++小程序,啥也不说了,直接贴源码:

注释里面是我写的时候的一些思考和写完之后的经验教训,给自己和其他初学c++的猿友们加油!

//教训:
//①(已改进!)代码复用度不够高,可以多新建几个局部函数(尤其是查找函数),或者是把这些函数添加进类里,
//就像Java一样,面向对象编程
//②(未改进!)用结构体来实现结点会好一些。
//③注意new (在堆区)和直接定义类(局部函数在栈上)的区别
//④区别指针和应用和对象本体的区别,特别是要注意有些不应该更改形参的地方,应该使用引用或者是const。
//⑤注意删除的时候一定要先令temp_2 =temp_1,temp_1 = temp_nextNode,最后再delete temp_2.否则会出现逻辑错误。
//⑥注意使用对象时用“.”使用对象的指针时用“->”
//⑦该通信录没有加入去重功能

需要源码的人直接从下面开始粘贴就好,把源码粘贴到编译器里就方面阅读了,第一次写博客,嫌麻烦,不想排版了。


#include<iostream>
#include <vector>

using namespace std;
//联系人链表
//使用类而不是结构体
class Person
{
    //默认是private权限,为了使外部程序可以访问应该写成public权限
public:
    string name;
public:
    string sex;
public:
    int age;
public:
    string num;
public:
    string addr;

    //运算符重载,判断两个person对象是否相等
    bool operator==(Person &a)//注意这里面使用引用比使用指针好,不会修改数据,
    {
        if (this->name == a.name && this->sex == a.sex &&
            this->age == a.age && this->num == a.num && this->addr == a.addr)
            return true;
        else
            return false;
    }

    //修改函数
public:
    void revise() {
        cout << "请输入联系人姓名:" << endl;
        cin >> this->name;
        cout << "请输入联系人性别:" << endl;
        cin >> this->sex;
        cout << "请输入联系人年龄:" << endl;
        cin >> this->age;
        cout << "请输入联系人电话号码:" << endl;
        cin >> this->num;
        cout << "请输入联系人地址:" << endl;
        cin >> this->addr;
    }
    //构造函数1
public:
    Person(string name, string sex, int age, string num, string addr)
        :name(name), sex(sex), age(age), num(num), addr(addr)
    {
        cout << "成功新建联系人"<<name<<"!" << endl;
    }
    //构造函数2
public:
    Person(){}
        
    //析构函数
public:
    ~Person() { ; }
};
class PersonList {
    //注意这里一定要写成public,不然下一个结点新建或者删除时,无法修改这些数据
    //说明链表的结点还是用结构体会好一些
public:
    Person* val;//注意这里只是一个指针
public:
    PersonList* nextNode;//指向下一个结点的指针
public:
    PersonList* beforeNode;

//遍历到当前链表的最后一个节点
public:
    PersonList* toEnd()//返回指向最后一个节点的指针
    {
        PersonList* res = this;
        //cout << this;
        //cout << this->beforeNode;
        while (res->nextNode != NULL) {
            res = res->nextNode;
        }
        //cout << res;
        return res;
    }
public:PersonList(Person* val, PersonList* beforeNode)
{
    this->val = val;
    this->beforeNode = beforeNode;
    //cout << "当前的list" << this << endl;
    if (beforeNode)
    {
        //cout << "已经在前一个结点添加指向该节点的指针" << endl;
        beforeNode->nextNode = this;//让前一个节点的下一个节点指向当前的这个节点
        //cout << "当前的list" << this << endl;
        //cout << "beforeNode的nextNode"<< beforeNode->nextNode << endl;
        //cout << "beforeNode的地址" << beforeNode << endl;
    }

        this->nextNode = NULL;

}
public:~PersonList() {
    //析构函数要完成:1.删除val指针指向的Person类 2.使上一个节点的nextNode指向当前nextNode
    //3.使下一个节点指向的beforeNode指向当前的beforeNode

    delete this->val;//!!!万分注意,这里里面的delete要应用于一个指针。不然就会报错!
    //因为第一个节点的beforeNode是head,所以无需要考虑上一个节点是否为空
    (this->beforeNode)->nextNode = this->nextNode;
    if((this->nextNode) != NULL)
        (this->nextNode)->beforeNode = this->beforeNode;
    //test
    //cout << "调用了PersonList的析构函数" << endl;

}
};

//显示菜单
void showMenu() {
    cout << "***************************" << endl;
    cout << "*****  1、添加联系人  *****" << endl;
    cout << "*****  2、显示联系人  *****" << endl;
    cout << "*****  3、删除联系人  *****" << endl;
    cout << "*****  4、查找联系人  *****" << endl;
    cout << "*****  5、修改联系人  *****" << endl;
    cout << "*****  6、清空联系人  *****" << endl;
    cout << "*****  0、退出通讯录  *****" << endl;
    cout << "***************************" << endl;


}

//添加联系人
void addContact(PersonList* head) {

    Person* ptr_person = new Person;
    //调用person类的修改函数来添加
    ptr_person->revise();
    
    //一定要用new,不然会在局部函数结束后自动析构掉局部函数创建的变量,因为直接
    //定义的话,该对象是在栈里新建的,局部函数执行完成之后,栈会自动弹出
    //如果是new,就是在堆区新建,不会自动析构
    
    new PersonList (ptr_person, head->toEnd());

    cout << "将联系人"<< ptr_person ->name<<"成功添加到通信录!" << endl;
    
    
};

//显示联系人
void showContacts(PersonList* head) {
    if (head->nextNode == NULL)
    {
        cout << "当前通信录为空" << endl;
        return;
    }
    PersonList* temp = head->nextNode;
    cout << "通信录所有内容如下:" << endl;
    while (temp != NULL)
    {
        cout << temp->val->name << "  "
            << temp->val->sex << "  "
            << temp->val->age << "  "
            << temp->val->num << "  "
            << temp->val->addr << endl;
        temp = temp->nextNode;
    }
}

//查找联系人,注意应该先定义查找,这样才能方便在删除函数中使用查找函数
void searchContacts(PersonList* head) {
    if (head->nextNode == NULL)
    {
        cout << "当前通讯录为空!" << endl;
        return;
    }

    Person person;
    vector<PersonList*> arr;//定义一个容器数组arr
    PersonList* temp = head->nextNode;//用temp来遍历数组
    cout << "请输入待查找联系人的姓名:" << endl;
    cin >> person.name;

    

    while (temp != NULL)
    {
        if (temp->val->name == person.name)
            arr.push_back(temp);//向vector末尾添加元素
        temp = temp->nextNode;
    }

    //通过vector的大小来确定下一步操作
    if(arr.size() == 0)
    {
        cout << "当前通讯录无此人!" << endl;
        return;
    }
    else 
    {
        cout << "查找到:" << endl;
        for (int i = 0; i < arr.size(); i++)
        {
            cout << arr[i]->val->name << "  "
                << arr[i]->val->sex << "  "
                << arr[i]->val->age << "  "
                << arr[i]->val->num << "  "
                << arr[i]->val->addr << endl;
        }
    }
}

//删除联系人(在查找联系人基础上修改)
void deleteContact( PersonList* head) {
    if (head->nextNode == NULL)
    {
        cout << "当前通讯录为空!" << endl;
        return;
    }

    //删除联系人首先用名字寻找,如果遇到同名的,就要求用户输入更多详细信息
    Person person;
    vector<PersonList*> arr;//定义一个容器数组arr
    PersonList* temp = head->nextNode;//用temp来遍历数组
    cout << "请输入待删除联系人的姓名:" << endl;
    cin >> person.name;

    

    while (temp != NULL)
    {
        if (temp->val->name == person.name)
            arr.push_back(temp);//向vector末尾添加元素
        temp = temp->nextNode;
    }

    //通过vector的大小来确定下一步操作
    switch (arr.size())
    {
    case 0:
        cout << "当前通讯录无此人!" << endl;
        return;
    case 1:
        delete arr[0];//delete会调用析构函数
        cout << "删除联系人" << person.name << "成功" << endl;
        return;
    default:
        cout << "存在" << arr.size() << "个同名联系人!输入0取消删除,输入1删除全部,输入2进行精确删除" << endl;
        break;
    }

    //此时说明存在同名联系人
    int flag = 0;//标记删除了几个联系人
    int r;//标记下一步动作
    cin >> r;
    switch (r)
    {
    case 1:
        for (int i = 0; i < arr.size(); i++)
            delete arr[i];
        cout << "已经删除" << arr. size()<< "个联系人!" << endl;
        break;
    case 2:
        cout << "请输入该联系人性别:" << endl;
        cin >> person.sex;
        cout << "请输入该联系人年龄:" << endl;
        cin >> person.age;
        cout << "请输入该联系人电话号码:" << endl;
        cin >> person.num;
        cout << "请输入该联系人地址:" << endl;
        cin >> person.addr;

        //这里要判断对象是否相等,使用运算符重载对两个对象进行直接判断
        
        for (int i = 0; i < arr.size(); i++)
        {
            if ((*arr[i]->val) == person)//由此可以看出解指针的优先级更低一些
            {
                delete arr[i];
                flag++;
            }
        }
        cout << "已经删除" << flag << "个联系人!" << endl;
        break;
    default:
        cout << "已经取消删除" << endl;
        return;
    }

}

//修改联系人(在删除函数基础上修改))
void reviseContacts(PersonList* head){
    if (head->nextNode == NULL)
    {
        cout << "当前通讯录为空!" << endl;
        return;
    }

    if (head->nextNode == NULL)
    {
        cout << "当前通讯录为空!" << endl;
        return;
    }

    //删除联系人首先用名字寻找,如果遇到同名的,就要求用户输入更多详细信息
    Person person;
    vector<PersonList*> arr;//定义一个容器数组arr
    PersonList* temp = head->nextNode;//用temp来遍历数组
    cout << "请输入待修改联系人的姓名:" << endl;
    cin >> person.name;

    while (temp != NULL)
    {
        if (temp->val->name == person.name)
            arr.push_back(temp);//向vector末尾添加元素
        temp = temp->nextNode;
    }

    //通过vector的大小来确定下一步操作
    switch (arr.size())
    {
    case 0:
        cout << "当前通讯录无此人!" << endl;
        return;
    case 1:
        arr[0]->val->revise();//调用revise函数,复用代码
        cout << "修改联系人" << person.name << "成功" << endl;
        return;
    default:
        cout << "存在" << arr.size() << "个同名联系人!请输入详细信息以确定修改哪一位联系人" << endl;
        person.revise();
        for (int i = 0; i < arr.size(); i++)
        {
            if ((*arr[i]->val) == person)
            {
                arr[i]->val->revise();//调用第一个符合条件的联系人的修改函数,只修改第一个!
                    //从这里还能看出面向对象的好处
                cout << "修改联系人"<<person.name<<"成功!" << endl;
                return;
            }
        }
        cout << "无符合条件的联系人!" << endl;
        break;
    }


}

//删除所有联系人
void deleteAllContacts(PersonList* head) {
    PersonList* temp_1 = head->nextNode;
    PersonList* temp_2 = NULL;//防止temp_2在通信录为空时,得不到初始化的问题。
    while (temp_1 != NULL)
    {
        temp_2 = temp_1;
        temp_1 = temp_1->nextNode;
        delete temp_2;
        
    }

    if (head->nextNode == NULL)
        cout << "已清空通讯录!" << endl;
}
//main函数
int main() {
    //test
    /*int a = 10;
    int* ptr_a = &a;
    int* ptr_b = ptr_a;
    cout << *ptr_a << endl << *ptr_b;*/
    //首先新建一个联系人链表的头
    PersonList* head = new PersonList(NULL, NULL);
     
    int select = 0;

    while (true) {
        //显示菜单
        showMenu();
        //获取选项
        cin >> select;
        //根据选项进行操作
        switch (select) {
        case 1: addContact(head);
            break;
        case 2: showContacts(head);
            break;
        case 3:deleteContact(head);
            break;
        case 4:searchContacts(head);
            break;
        case 5:reviseContacts(head);
            break;
        case 6:deleteAllContacts(head);
            break;
        case 0:
            return 0;
        default:
            break;
        }


        //

    }

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值