c++ --- 通讯录管理系统(多文档编程、文件 *** 作、链表)

c++ --- 通讯录管理系统(多文档编程、文件 *** 作、链表),第1张

c++ --- 通讯录管理系统(多文档编程、文件 *** 作、链表)

节点关系

node.h

#pragma once
class MM;
class Node{
public:
	Node();
	Node(MM *data);
	Node(MM *data,Node* next);
	Node*& getNext();    //返回指针的引用,用于访问它里面的指针
	MM*& getData();      //提供公有接口,用于访问它里面的数据
protected:
	MM *data;
	Node* next;
};

node.cpp 

.h要避免头文件包含(避免头文件的重复包含)---- 在.cpp中包含头文件即可

头插法实现数据插入---新插入的数据在最前面

#include "node.h"    //用到了Node节点,需要包含头文件node.h 
#include "mm.h"
Node::Node()
{
	this->next = nullptr;//无参构造函数 直接把指针置为空
}

Node::Node(MM* data)
{
	this->data = data;   //把数据做初始化,再把指针置为空  或 统一采用初始化参数列表的方式
	this->next = nullptr;
}

Node::Node(MM* data, Node* next)
{
	this->data = data;
	this->next = next;
}

Node*& Node::getNext()
{
	return next;
}

MM*& Node::getData()
{
	// TODO: 在此处插入 return 语句
	return data;
}

实现链表增删改查

list.h

#pragma once
#include "mm.h"
#include "node.h"
//无头链表:表头存数据(这里实现的是有头链表 *** 作)
//有头链表:表头不存数据
class list 
{
public:
	list();
	void insertList(MM* data);          //采用头插法插入数据
	void printList();                   //打印链表中的数据
 
	void deleteAppoin(string posData);  //删除链表中的数据,根据姓名做删除
	Node* searchByData(string posData); //查找链表中的数据,根据姓名做查找

	void saveListToFile(const char* fileName); //文件 *** 作,把链表的数据流到文件中
	void readFileToList(const char* fileName); //把文件的数据流到链表中
protected:
	Node* headNode;
	int curSize;    //当前节点个数
};

list.cpp 

删除表头,要改变表头的指向 第一个节点是要删除的节点要 单独处理

处理删除表头的情况:

1. 记录当前节点的(表头)下一个节点     2. 释放表头

//删除的是表头
    Node* nextNode = curNode->getNext();
    delete headNode;
    headNode = nextNode;
    this->curSize--;    //删除成功改变size

 处理删除链表中某个数据的情况:

//删除链表中的数据
    preNode->getNext() = curNode->getNext();
    delete curNode;
    curNode = nullptr;
    this->curSize--;    //删除成功改变size
#include "list.h"
#include 
using namespace std;
list::list()
{
    this->headNode = nullptr;
    this->curSize = 0;
}
//头插法
void list::insertList(MM* data) 
{
    //表头插入
    headNode = new Node(data, headNode);
    this->curSize++;
}
//打印链表
void list::printList()
{
    Node* pmove = headNode;
    cout << "name" << "t" << "age" << "t" << "tel" << "t" << "sex" << endl;
    while (pmove != nullptr) 
    {
        //cout << pmove->getData() << endl;
        pmove->getData()->printMM();
        pmove = pmove->getNext();
    }
}
//删除链表
void list::deleteAppoin(string posData)
{
    Node* preNode = headNode;
    Node* curNode = headNode;
    while (curNode!=nullptr&&curNode->getData()->getName() != posData) 
    {
        preNode = curNode;
        curNode = curNode->getNext();
    }
    if (curNode == nullptr)       //如果链表为空,说明没找到
    {
        cout << "删除失败!" << endl;
    }
    else if (curNode == preNode)  //删除的节点是第一个节点,代表删除表头
    {
        Node* nextNode = curNode->getNext();
        delete headNode;
        headNode = nextNode;
        this->curSize--;
    }
    else 
    {
        preNode->getNext() = curNode->getNext();
        delete curNode;
        curNode = nullptr;
        this->curSize--;         //删除成功改变size
    }
}
//查找链表中数据
Node* list::searchByData(string posData)
{
    Node* pmove = headNode;
    while (pmove!=nullptr&&pmove->getData()->getName() != posData) 
    {
        pmove = pmove->getNext();
    }
    return pmove;
}
//文件 *** 作---从链表流入文件
void list::saveListToFile(const char* fileName)
{
    fstream save(fileName, ios::out);
    Node* pmove = headNode;
    while (pmove != nullptr) 
    {
        pmove->getData()->saveFile(save);
        pmove = pmove->getNext();
    }
    save.close();
}
//文件 *** 作---从文件流入链表
void list::readFileToList(const char* fileName)
{
    fstream read(fileName, ios::in);
    while (1) 
    {
        MM* mm = new MM;
        mm->readFile(read);
        if (read.eof())
            break;
        insertList(mm);
    }
    read.close();
}

代码解析 

文件 *** 作解析:

        ~所有数据存在链表中,对链表做封装文件 *** 作

        ~代码中做了数据的修改的地方,就要做一下文件的保存 *** 作---修改成功后、插入、删除

pList->saveListToFile("1.txt");
//文件 *** 作---从链表流入文件  写
void list::saveListToFile(const char* fileName)
{
    fstream save(fileName, ios::out);
    Node* pmove = headNode;
    while (pmove != nullptr) 
    {
        pmove->getData()->saveFile(save);    //直接调用saveFile()
        pmove = pmove->getNext();
    }
    save.close();
}
//文件 *** 作---从文件流入链表  读
void list::readFileToList(const char* fileName)
{
    fstream read(fileName, ios::in);
    while (1) 
    {
        MM* mm = new MM;   //因为存的是指针,所以每个数据都要new一个对象出来,要有无参构造函数
        mm->readFile(read);//把数据读到链表中去

        if (read.eof())    //最后一个读取不应该把数据读到链表中(多读了一次),否则会有乱码
            break;
        insertList(mm);    //把对象存到链表中去
    }
    read.close();
}

测试链表的代码 

int main()
{
        list myList;     //或者new一个对象出来
//插入3个数据
    for(int i=0;i<3;i++){

        myList.insert[i];//需要手动写析构函数

    }
        myList.printlist();  //打印数据
}

 mm.h---通讯录中包含的人物数据        单独描述成一个类

// 提供一些方法能够打印对象,能够打印数据

注意:

需要改链表存储数据的类型---管理的是MM类的数据

链表的删除、查找 由(通过数据做查找)改为 通过姓名做删除、查找

#pragma once
class MM;
class Node{
public:
	Node();
	Node(MM *data);
	Node(MM *data,Node* next);
	Node*& getNext();    
	MM*& getData();      
protected:
	MM *data;    //如果用MM data需要包含头文件#include "mm.h",否则会报错
	Node* next;
};

//用指针MM* 不会报错, 指针只是声明一下,创建对象要已经存在,对象要有创建的过程
#pragma once
#include 
#include 
#include 
using namespace std;
class MM 
{
public:
	MM(string name, int age, string tel, string sex);
	MM();
	void printMM();
	void saveFile(fstream& file);    //把链表中的数据存到文件中--->流进去
	void readFile(fstream& file);    //读取文件的数据到链表--->流出来
	string& getName();
	int& getAge();
	string& getTel();
	string& getSex();
protected:
	string name;    //通讯录的数据
	int age;
	string tel;
	string sex;
};

 mm.cpp

#include "mm.h"

MM::MM(string name, int age, string tel, string sex):name(name),age(age),tel(tel),sex(sex)
{

}

MM::MM()
{

}

void MM::printMM()
{
	cout << name << "t" << age << "t" << tel << "t" << sex << endl;
}

void MM::saveFile(fstream& file)    //提供保存数据的接口
{
	file << name << " " << age << " " << tel << " " << sex << endl; //直接把数据流到文件中
}
void MM::readFile(fstream& file)
{
	file >> name >> age >> tel >> sex;    //分别流到name,age中,流出来忽视空格
}

string& MM::getName()
{
	return name;
}

int& MM::getAge()
{
	// TODO: 在此处插入 return 语句
	return age;
}

string& MM::getTel()
{
	// TODO: 在此处插入 return 语句
	return tel;
}

string& MM::getSex()
{
	// TODO: 在此处插入 return 语句
	return sex;
}

 MMSystem.h---实现通讯录人物增删改查功能的函数

#pragma once
#include "list.h"
class MMSystem
{
public:
	MMSystem();        
	void MakeMenu();   //菜单
	void KeyDown();    //交互处理
	void insertMM();   //插入数据(查找数据、删除数据也可以封装成函数)

	list*& getPList(); //提供接口访问属性pList
protected:
	list* pList;
};

在当前文件夹中新建一个1.txt 文本文档---用于处理链表流出来的数据 和 把数据流到链表中

MMSystem.cpp

#include "MMsystem.h"

MMSystem::MMSystem():pList(new list)    //类的组合:以另一个对象为数据成员
{
    pList->readFileToList("1.txt");     //对象创建完后要把存在 1.txt 中的数据加载到链表中
}

void MMSystem::MakeMenu()
{
    cout << "----------------【通讯录】------------------" << endl;
    cout << "tt0.退出系统" << endl;
    cout << "tt1.插入数据" << endl;
    cout << "tt2.删除数据" << endl;
    cout << "tt3.查找数据" << endl;
    cout << "tt4.修改数据" << endl;
    cout << "tt5.浏览数据" << endl;
    cout << "--------------------------------------------" << endl;
}

void MMSystem::KeyDown()
{
    int userKey = 0;
    //new对象准备的变量
    string name;
    Node* result;    //准备一个指针变量,因为返回的是一个指针变量
    cin >> userKey;
    switch (userKey) 
    {
    case 0:
        exit(0);
        break;
    case 1:
        this->insertMM();
        pList->saveListToFile("1.txt");
        break;
    case 2:
        cout << "请输入需要删除的姓名:";    //这里可以封装成函数处理,类似 insertMM();
        cin >> name;
        pList->deleteAppoin(name);
        pList->saveListToFile("1.txt");
        break;
    case 3:
        cout << "请输入需要查找的姓名:";
        cin >> name;
        result = pList->searchByData(name);
        if (result == nullptr)
        {
            cout << "查无此人!" << endl;
        }
        else 
        {
            cout << "查找信息如下:" << endl;
            result->getData()->printMM();
        }
        break;
    case 4:
        cout << "请输入要修改的姓名:";
        cin >> name;
        result = pList->searchByData(name);    //通过姓名做查找
        if (result == nullptr)
        {
            cout << "查无此人!无法修改" << endl;
        }
        else
        {
            cout << "请输入修改的信息:" << endl;
            cin >> result->getData()->getName()
                >> result->getData()->getAge()
                >> result->getData()->getTel()
                >> result->getData()->getSex();
            cout << "修改成功" << endl;
            pList->saveListToFile("1.txt");
        }
        break;
    case 5:
        pList->printList();
        break;
    }
}
void MMSystem::insertMM()    //new对象准备的变量
{
    string name;
    int age;
    string tel;    //电话
    string sex;    //性别
    cout << "请分别输入姓名、年龄、电话号码、性别:" << endl;
    cin >> name >> age >> tel >> sex;
    pList->insertList(new MM(name, age, tel, sex));
}
list*& MMSystem::getPList()
{
    // TODO: 在此处插入 return 语句
    return pList;
}

 c++管理系统.cpp---主函数部分

#include "MMsystem.h"
#include 
int main() 
{
	MMSystem* pSystem = new MMSystem;
	while (1) 
	{
		pSystem->MakeMenu();
		pSystem->KeyDown();
		system("pause");
		system("cls");
	}
	return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5657966.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存