学生通讯录管理系统(链表实现)

第一章 设计要求

1.1 问题描述
使用C或C++实现一个通讯录管理系统,具有实现通讯录的建立和输出、通讯者的插入、 删除和查询等几种操作功能。
1.2 需求分析
1.2.1 需求概述
通讯录管理系统是一个比较实用的小型管理系统。随着生活节奏的加快,人们追求丰富便捷的电子产品体验,因此也提高对便捷方式的喜爱。当今社会下人们的交际范围越来越广泛,通讯录系统的出现,方便了人们存储通讯录,便于人们日常的交际。为方便广大人们对通讯管理系统的使用,本设计采用控制语句来改变程序各项功能的实现。主菜单部分主要解决的问题是程序开始选择问题,以及循环选择问题,其余各部分根据其实现功能完成代码设计。
1.2.2 环境需求
本课程设计需要的设备为硬件要求和软件配置要求具体要求如下:
(1)硬件要求:一台计算机。
(2)软件配置:Windows、MinGW 32、CLion2020.2 IDE编译工具。
1.2.3 功能需求
本课程设计是利用数据结构的相关知识在 MinGW编译工具和CLion IDE下用 C++ 实现一个通讯录管理系统。具有实现通讯录的建立和输出、通讯者的插入、删除和查询等几种操作功能。

第二章 概要设计

2.1 主界面设计
主界面设计代码如下图2.1.1所示:
学生通讯录管理系统(链表实现)_第1张图片

图 2.1.1主界面代码图

主界面设计图如下图2.1.2所示:
学生通讯录管理系统(链表实现)_第2张图片

图 2.1.2 主界面图
2.2 存储结构设计
声明一个结构体作为链表单个节点,其中存储的内容有学号、姓名、出生日期、电话号和家庭住址,这些节点利用指针连接起来。存储结构设计代码如下图2.2所示:
学生通讯录管理系统(链表实现)_第3张图片

图 2.2存储结构设计图
2.3 系统功能设计
(1) 菜单功能:输出菜单界面,并提供一个菜单来实现各个函数的调用以及提示用户。
(2) 添加功能:包含输入功能,第一次可以一次完成若干条记录的输入,此后可每次完成一条记录的输入,增加通讯录的基本信息。
(3) 修改功能:根据联系人的名字,修改指定联系人的信息。
(4) 删除功能:根据联系人的名字,删除指定联系人的信息。
(5) 查询功能:根据联系人的名字,查找指定联系人的信息并输出。
(6) 显示功能:将目前所有的联系人的信息输出。
(7) 读取功能:从保存的文件中读取通讯录信息;
(8) 保存功能:保存现有通讯录到文件中,防止程序退出数据丢失;
(9) 关闭功能:退出程序。

第三章 模块设计

3.1 模块设计
3.1.1 功能模块设计
系统的功能模块包括通讯录链表的建立、通讯者结点的插入、通讯者结点的查询、通讯者结点的删除、通讯者结点的修改、通讯录链表的输出、向/从文件中写入或读取通讯录和退出通讯录管理系统,如下图3.1.1所示:
学生通讯录管理系统(链表实现)_第4张图片
图3.1.1 功能图

3.1.2 系统流程图
系统流程如下图3.1.2所示:
学生通讯录管理系统(链表实现)_第5张图片

图 3.1.2系统流程图
3.2 系统子程序及功能设计
系统子程序功能设计一览表如下表3.2.1:

函数名 功能
void Menu(); 显示菜单
Node *Create(); 新建通讯录链表
bool InsertStudent(Node *head); 插入学生信息
bool DeleteStudent(Node *head, const string& id); 删除学生信息
Node *ReadFromFile(); 从文件中读取通讯录
bool WriteToFile(Node *head); 向文件写入通讯录
Node * FindStudent(Node *head, const string& id); 查询学生信息(学号)
Node* FindStuInformation(const string& pName, Node* pHead); 查询学生信息(姓名)
void PrintStudent(Node *head); 输出全部学生信息
void PrintStudentSingle(Node *pNode); 输出单个学生节点信息
bool ChangeInformation(Node* pNode); 修改学生信息
void SYS_CONTROL(); 系统控制函数

表3.2.1 功能函数一览表
(1) 创建通讯录方法如下图3.2.1所示:
学生通讯录管理系统(链表实现)_第6张图片
图3.2.1 Create方法

(2) 删除信息方法如下图3.2.2所示:
学生通讯录管理系统(链表实现)_第7张图片

图3.2.2 deletestudent方法
(3) 查询学生信息方法如下图3.2.3所示:
学生通讯录管理系统(链表实现)_第8张图片

图3.2.3 Findstudent方法
(4) 插入学生信息方法如下图3.2.4所示:
学生通讯录管理系统(链表实现)_第9张图片

图3.2.4 Insertstudent
(5) 打印学生信息功能如下图3.2.5所示:
学生通讯录管理系统(链表实现)_第10张图片
图3.2.5 Printstudent

(6) 从文件中读取通讯录功能如下图3.2.6所示:
学生通讯录管理系统(链表实现)_第11张图片

图3.2.6 Readfromfile
(7) 保存通讯录功能如下图3.2.7所示:
学生通讯录管理系统(链表实现)_第12张图片

图3.2.7 Writeinfile

(8) 修改功能流程图如下图3.2.8所示:
学生通讯录管理系统(链表实现)_第13张图片
图3.2.8 修改功能流程图

3.3 函数主要调用关系图

函数主要调用关系如下图3.3所示:
学生通讯录管理系统(链表实现)_第14张图片
图3.3.1 函数主要关系调用图

第四章 详细设计

4.1 数据定义
系统的数据定义如下图4.1所示:学生通讯录管理系统(链表实现)_第15张图片图4.1 链表节点数据定义图
4.2 系统主要子程序详细设计
4.2.1 通讯录链表建立

Node *Create() {
    int i = 1;
    char ch = 'Y';                  // 是否继续输入学生通讯录信息
    Node *head = new Node();       // 头结点,不存放数据
    if(nullptr == head) {
        cerr << "内存空间分配失败" << endl;
        exit(1);
    }
    head->next = nullptr;
    while(ch == 'Y'||ch == 'y') {
        cout << "请输入第" << i << "位学生的学号、姓名、出生日期、姓别(1:表示是男生,0:表示是女生)、电话和地址(以空格隔开):" << endl;
        Node *newNode = new Node();  // 新建结点
        if(nullptr == newNode) {
            cerr << "内存空间分配失败" << endl;
            exit(1);
        }
        cin >> newNode->id >> newNode->name >> newNode->birthday >> newNode->sex >> newNode->phone >> newNode->address;
        newNode->next = nullptr;
        // 采用头插入
        newNode->next = head->next;  // 新结点的next保存首结点(头结点的下一个结点)
        head->next = newNode;       // 头指针往前移
        i++;
        cout << "是否继续输入学生的通讯录信息?(Y/N):";
        cin >> ch;
    }
    return head;
}

4.2.2 插入节点学生信息

bool InsertStudent(Node *head) {
    cout << "请输入学生的学号、姓名、出生日期、姓别(1:表示是男生,0:表示是女生)、电话和地址(以空格隔开):" << endl;
    Node *newNode = new Node();	   // 新建结点
    if(nullptr == newNode) {
        cerr << "内存空间分配失败" << endl;
        exit(1);
    }
    cin >> newNode->id >> newNode->name >> newNode->birthday >> newNode->sex >> newNode->phone >> newNode->address;
    newNode->next = head->next;	  // 新结点的next保存首结点(头结点的下一个结点)
    head->next = newNode;        	  // 头指针往前移
    return true;                     // 插入成功
}

4.2.3 删除节点学生信息

bool DeleteStudent(Node *head, const string& id) {
    Node *prev = head;
    Node *p = head->next;

    while(p != nullptr && p->id != id) {		//注意二者不可交换位置
        prev = p;
        p = p->next;
    }
    if(p == nullptr)return false;
    prev->next = p->next;
    delete p;
    p = nullptr;
    return true;		//删除成功
}

4.2.4 查询节点学生信息

// 在通讯录中查询学生信息(按学号查询)
Node* FindStudent(Node *head, const string& id) {
    Node *p = head;
    int count = 0;
    while(p != nullptr && id != p->id) {		//注意二者不可交换位置
        p = p->next;
        ++count;
    }
    for (int i=0;i<count-1;i++)				//查找对应节点指针
    {
        head = head->next;
    }
    if(p == nullptr)return p; else return head;   //分情况返回,防止野指针
}

// 在通讯录中查询学生信息(按姓名查询)
Node* FindStuInformation(const string& pName, Node* pHead) {
    Node *p = pHead;
    int count = 0;
    while(p != nullptr && pName != p->name) {	//注意二者不可交换位置
        p = p->next;
        ++count;
    }
    for (int i=0;i<count-1;i++)					//查找对应节点指针
    {
        pHead = pHead->next;
    }
    if(p == nullptr)return p; else return pHead;		//分情况返回,防止野指针
}

4.2.5 修改节点学生信息

bool ChangeInformation(Node *pNode) {
    Node* p = pNode->next;
    int ch = -1;
    string str = "INIT";
    cout<<"按编号选择需要修改的项目,【按0】退出"<<endl;
    while(ch != 0){
        cin>>ch;
        switch (ch) {
            case 1:
                cout<<"修改学号为:"<<endl;
                cin>>str;
                p->id = str;
                cout<<"继续按编号选择需要修改的项目,或【按0】退出"<<endl;
                break;
            case 2:
                cout<<"修改姓名为:"<<endl;
                cin>>str;
                p->name = str;
                cout<<"继续按编号选择需要修改的项目,或【按0】退出"<<endl;
                break;
            case 3:
                cout<<"修改出生日期为:"<<endl;
                cin>>str;
                p->birthday = str;
                cout<<"继续按编号选择需要修改的项目,或【按0】退出"<<endl;
                break;
            case 4:
                p->sex = !(p->sex);
                str = "Changed by [4](sex)";
                cout<<"性别已修改!"<<endl;
                cout<<"继续按编号选择需要修改的项目,或【按0】退出"<<endl;
                break;
            case 5:
                cout<<"修改电话号为:"<<endl;
                cin>>str;
                p->phone = str;
                cout<<"继续按编号选择需要修改的项目,或【按0】退出"<<endl;
                break;
            case 6:
                cout<<"修改家庭地址为:"<<endl;
                cin>>str;
                p->address = str;
                cout<<"继续按编号选择需要修改的项目,或【按0】退出"<<endl;
                break;
            case 0:
                break;
            default:
                cout<<"选择错误,请重新选择!"<<endl;
        }
    }
    if ( str == "INIT")return false; else return true;
}

4.2.6 保存通讯录

bool WriteToFile(Node *head) {
    if (head == nullptr){PLCR return false;}
    Node *p = head->next;
    int ch = 0,flag = 1;
    while (flag){
        cout<<"[0]覆盖原有通讯录 [1]添加到原有通讯录"<<endl;
        cin>>ch;
        switch (ch) {
            case 0:
                flag = 0;
                break;
            case 1:
                flag = 0;
                break;
            default:
                cout<<"选择错误"<<endl;
        }
    }
    // 以写模式打开文件
ofstream outFile;
if(ch){outFile.open("StuMessageFile/student.txt",ios::out|ios::app);}else{outFile.open("StuMessageFile/student.txt", ios::out);};
    if(!outFile)
    {
        cout << "Error: opening file fail" << endl;
        exit(1);
    }
    while(p != nullptr) {
        // 写入文件
        outFile << p->id << " " << p->name << " " << p->birthday << " " << p->sex << " " << p->phone << " " << p->address << endl;
        p = p->next;      // 往后移
    }
    return true;
}

4.2.7 读取通讯录

Node *ReadFromFile() {
    Node *head = new Node();		// 头结点,不存放数据
    if(nullptr == head) {
        cerr << "内存空间分配失败" << endl;
        exit(1);
    }
    ifstream inFile;
    inFile.open("StuMessageFile/student.txt", ios::in);		// 以读的方式打开文件
    if(!inFile.is_open())
    {
        cout << "Error: opening file fail" << endl;
        exit(1);
    }
    Node *newNode = new Node();		// 新建结点
    if(nullptr == newNode) {
        cerr << "内存空间分配失败" << endl;
        exit(1);
    }
    while(!inFile.eof()) {		// 当未到文件尾
        Node *newNode = new Node();       // 新建结点
        if(nullptr == newNode) {
            cerr << "内存空间分配失败" << endl;
            exit(1);
        }
        // 从文件中输入数据
        inFile >> newNode->id >> newNode->name >> newNode->birthday >> newNode->sex >> newNode->phone >> newNode->address;
        newNode->next = head->next;		// 新结点的next保存首结点(头结点的下一个结点)
        head->next = newNode;		// 头指针往前移
    }
    inFile.close();		// 关闭文件
    head = head->next;
    return head;
}

第五章 测试分析

5.1 遇到的问题及解决方法

  1. 问题:
    (1) 在未创建或未读取通讯录的情况下,选择其他功能程序会崩溃;
    (2) 保存通讯录后,覆盖原有学生信息文件;
    (3) 查询并打印时,打印出被查询学生后的所有学生信息;
    (4) 打印通讯录所有学生信息时,未存储任何信息的头结点被打印;
    (5) 程序测试时,控制台乱码显示中文字符。
  2. 解决办法:
    (6) 在主程序Switch()case……中添加头结点判断;
    (7) 修改文件的打开方式为:追加写入方式;
    (8) 重写PrintStudentSingle函数,取消while(p != nullptr)循环条件;
    (9) 将头结点跳过,从下一个开始,head = head->next;
    (10) 编写程序选择UTF-8编码格式,控制台调试选择GBK编码。

5.2 经验和体会
(1)通过本次项目使我们进一步理解和掌握课堂上所学各种基本抽象数据类型的逻辑结构、存储结构和操作实现算法,以及它们在程序中的使用方法。
(2)使我们掌握软件设计的基本内容和设计方法,并培养了我们进行规范化软件设计的能力。
(3)使我们能掌握使用各种计算机资料和有关参考资料,提高我们进行程序设计的基本能力。

5.3 测试功能展示
(1) 主界面如下图5.3.1所示:
学生通讯录管理系统(链表实现)_第16张图片
图5.3.1 主界面

(2) 通讯录链表建立(1. 新建学生通讯录)功能测试如下图5.3.2所示:
学生通讯录管理系统(链表实现)_第17张图片
图5.3.2 新建通讯录

(3) 插入节点学生信息(2. 在通讯录插入学生信息)测试如下图5.3.3所示:
学生通讯录管理系统(链表实现)_第18张图片
图5.3.3 插入信息

(4) 删除节点学生信息功能(3. 在通讯录删除学生信息)测试如下图5.3.4所示:
学生通讯录管理系统(链表实现)_第19张图片
图5.3.4 删除信息

(5) 查询节点学生信息功能(6. 在通讯录按学号查询信息)测试如下图5.4.5所示:
学生通讯录管理系统(链表实现)_第20张图片
图5.4.5 查询信息

(6) 修改节点学生信息(8. 修改学生信息)功能测试如下图5.4.6所示:

学生通讯录管理系统(链表实现)_第21张图片
图5.4.6 修改学生信息

(7) 保存通讯录(5. 向文件写入通讯录信息)功能如下图所示:
学生通讯录管理系统(链表实现)_第22张图片
图5.4.7 保存通讯录

(8) 读取通讯录(4. 从文件读取通讯录信息)功能测试如下图5.4.8所示;
学生通讯录管理系统(链表实现)_第23张图片
图5.4.8 读取通讯录

第六章 源程序清单

6.1 main.cpp

#include "student.h"
using namespace std;

int main() {
    SYS_CONTROL();
    return 0;
}

6.2 student.cpp

//
// Created by Today me on 2021/6/21.
//

#include "student.h"
//string id; 			// 学生的学号
//string name; 		// 姓名
//string birthday; 		// 出生日期:如1995-01-01
//int sex;             // 1:表示是男生,0:表示是女生
//string phone;        // 电话
//string address;       // 地址

// 新建学生通讯录信息
// 如:1110618014058 Thomas 2000-01-01 1 13521469978 陕西汉中

// 菜单界面
void Menu() {
    SYSTEMTIME sys;
    GetLocalTime(&sys);
    cout << "\t\t************************************\n\t\t**^_^欢迎使用学生通讯录管理系统^_^**\n\t\t************************************\n\t\t\t   "<<sys.wYear<<"年"<<sys.wMonth<<"月"<<sys.wDay<<"日";cout<<"\n****************************************************************\n**\t\t\t通讯录管理主菜单\t\t      **\n**------------------------------------------------------------**\n";
    cout << "**|   1.新建学生通讯录\t\t 5.向文件写入通讯录信息      |**\n";
    cout << "**|   2.在通讯录插入学生信息\t 6.在通讯录按学号查询信息    |**\n";
    cout << "**|   3.在通讯录删除学生信息\t 7.在屏幕打印全部学生信息    |**\n";
    cout << "**|   4.从文件读取通讯录信息\t 8.修改学生信息\t\t     |**\n**------------------------------------------------------------**\n****************************************************************\n";
    cout << "**\t\t请输入选择(1-8):【0】退出系统              **\n****************************************************************\n";
}
// 创建通讯录
Node *Create() {
    int i = 1;
    char ch = 'Y';                // 是否继续输入学生通讯录信息
    Node *head = new Node();     // 头结点,不存放数据
    if(nullptr == head) {
        cerr << "内存空间分配失败" << endl;
        exit(1);
    }
    head->next = nullptr;
    while(ch == 'Y'||ch == 'y') {
        cout << "请输入第" << i << "位学生的学号、姓名、出生日期、姓别(1:表示是男生,0:表示是女生)、电话和地址(以空格隔开):" << endl;
        Node *newNode = new Node();     // 新建结点
        if(nullptr == newNode) {
            cerr << "内存空间分配失败" << endl;
            exit(1);
        }
        cin >> newNode->id >> newNode->name >> newNode->birthday >> newNode->sex >> newNode->phone >> newNode->address;
        newNode->next = nullptr;
        // 采用头插入
        newNode->next = head->next;  // 新结点的next保存首结点(头结点的下一个结点)
        head->next = newNode;       // 头指针往前移
        i++;
        cout << "是否继续输入学生的通讯录信息?(Y/N):";
        cin >> ch;
    }
    return head;
}

// 向学生通讯录插入学生信息
bool InsertStudent(Node *head) {
    cout << "请输入学生的学号、姓名、出生日期、姓别(1:表示是男生,0:表示是女生)、电话和地址(以空格隔开):" << endl;
    Node *newNode = new Node();    // 新建结点
    if(nullptr == newNode) {
        cerr << "内存空间分配失败" << endl;
        exit(1);
    }
    cin >> newNode->id >> newNode->name >> newNode->birthday >> newNode->sex >> newNode->phone >> newNode->address;
    newNode->next = head->next;    // 新结点的next保存首结点(头结点的下一个结点)
    head->next = newNode;          // 头指针往前移
    return true;                    // 插入成功
}

// 在通讯录中删除学生信息
bool DeleteStudent(Node *head, const string& id) {
    Node *prev = head;
    Node *p = head->next;

    while(p != nullptr && p->id != id) {       //注意二者不可交换位置
        prev = p;
        p = p->next;
    }
    if(p == nullptr)return false;
    prev->next = p->next;
    delete p;
    p = nullptr;
    return true;
}

// 从文件中读取通讯录信息
Node *ReadFromFile() {
    Node *head = new Node();      // 头结点,不存放数据
    if(nullptr == head) {
        cerr << "内存空间分配失败" << endl;
        exit(1);
    }
    ifstream inFile;
    inFile.open("StuMessageFile/student.txt", ios::in);      // 以读的方式打开文件
    if(!inFile.is_open())
    {
        cout << "Error: opening file fail" << endl;
        exit(1);
    }
    Node *newNode = new Node();       // 新建结点
    if(nullptr == newNode) {
        cerr << "内存空间分配失败" << endl;
        exit(1);
    }
    while(!inFile.eof()) {               // 当未到文件尾
        Node *newNode = new Node();  // 新建结点
        if(nullptr == newNode) {
            cerr << "内存空间分配失败" << endl;
            exit(1);
        }
        // 从文件中输入数据
        inFile >> newNode->id >> newNode->name >> newNode->birthday >> newNode->sex >> newNode->phone >> newNode->address;
        newNode->next = head->next;  // 新结点的next保存首结点(头结点的下一个结点)
        head->next = newNode;       // 头指针往前移
    }
    inFile.close();                   // 关闭文件
    head = head->next;
    return head;
}

// 向文件写入学生通讯录信息
bool WriteToFile(Node *head) {
    if (head == nullptr){PLCR return false;}
    Node *p = head->next;
    int ch = 0,flag = 1;
    while (flag){
        cout<<"[0]覆盖原有通讯录 [1]添加到原有通讯录"<<endl;
        cin>>ch;
        switch (ch) {
            case 0:
                flag = 0;
                break;
            case 1:
                flag = 0;
                break;
            default:
                cout<<"选择错误"<<endl;
        }
    }
    // 以写模式打开文件
ofstream outFile;
if(ch){outFile.open("StuMessageFile/student.txt",ios::out|ios::app);}else{outFile.open("StuMessageFile/student.txt", ios::out);};
    if(!outFile)
    {
        cout << "Error: opening file fail" << endl;
        exit(1);
    }
    while(p != nullptr) {
        // 写入文件
        outFile << p->id << " " << p->name << " " << p->birthday << " " << p->sex << " " << p->phone << " " << p->address << endl;
        p = p->next;             // 往后移
    }
    return true;
}

// 在通讯录中查询学生信息(按学号查询)
Node* FindStudent(Node *head, const string& id) {
    Node *p = head;
    int count = 0;
    while(p != nullptr && id != p->id) {
        p = p->next;
        ++count;
    }
    for (int i=0;i<count-1;i++)
    {
        head = head->next;
    }
    if(p == nullptr)return p; else return head;
}

// 在屏幕中输出全部学生信息
void PrintStudent(Node *head) {
    Node *p = head->next;
    while(p != nullptr) {
        cout << "学号:" << p->id << " 姓名:" << p->name << " 出生日期:" << p->birthday;
        if(p->sex == 1)
            cout << " 性别:男";
        else
            cout << " 性别:女";
        cout << " 电话:" << p->phone << " 地址:" << p->address << endl;
        p = p->next;
    }
}

// 单行输出功能
void PrintStudentSingle(Node *pNode) {
    Node* p = pNode->next;
    cout << "【1】学号:" << p->id << " 【2】姓名:" << p->name << " 【3】出生日期:" << p->birthday;
    if(p->sex == 1)
        cout << " 【4】性别:男";
    else
        cout << " 【4】性别:女";
    cout << " 【5】电话:" << p->phone << " 【6】地址:" << p->address << endl;

}

// 在通讯录中查询学生信息(按姓名查询)
Node* FindStuInformation(const string& pName, Node* pHead) {
    Node *p = pHead;
    int count = 0;
    while(p != nullptr && pName != p->name) {
        p = p->next;
        ++count;
    }
    for (int i=0;i<count-1;i++)
    {
        pHead = pHead->next;
    }
    if(p == nullptr)return p; else return pHead;
}
//查找所有符合条件的学生
void FindAll(Node* pNode,const string& pName)
{
    Node* p = pNode;
    while (pNode != nullptr)
    {
        if (pName == pNode->name)PrintStudentSingle(p);
        p = pNode;
        pNode = pNode->next;
    }
}
// 修改学生信息
bool ChangeInformation(Node *pNode) {
    Node* p = pNode->next;
    int ch = -1;
    string str = "INIT";
    cout<<"按编号选择需要修改的项目,【按0】退出"<<endl;
    while(ch != 0){
        cin>>ch;
        switch (ch) {
            case 1:
                cout<<"修改学号为:"<<endl;
                cin>>str;
                p->id = str;
                cout<<"继续按编号选择需要修改的项目,或【按0】退出"<<endl;
                break;
            case 2:
                cout<<"修改姓名为:"<<endl;
                cin>>str;
                p->name = str;
                cout<<"继续按编号选择需要修改的项目,或【按0】退出"<<endl;
                break;
            case 3:
                cout<<"修改出生日期为:"<<endl;
                cin>>str;
                p->birthday = str;
                cout<<"继续按编号选择需要修改的项目,或【按0】退出"<<endl;
                break;
            case 4:
                p->sex = !(p->sex);
                str = "Changed by [4](sex)";
                cout<<"性别已修改!"<<endl;
                cout<<"继续按编号选择需要修改的项目,或【按0】退出"<<endl;
                break;
            case 5:
                cout<<"修改电话号为:"<<endl;
                cin>>str;
                p->phone = str;
                cout<<"继续按编号选择需要修改的项目,或【按0】退出"<<endl;
                break;
            case 6:
                cout<<"修改家庭地址为:"<<endl;
                cin>>str;
                p->address = str;
                cout<<"继续按编号选择需要修改的项目,或【按0】退出"<<endl;
                break;
            case 0:
                break;
            default:
                cout<<"选择错误,请重新选择!"<<endl;
        }
    }
    if ( str == "INIT")return false; else return true;
}

// 系统控制函数
void SYS_CONTROL() {
    SetConsoleTitle("学生通讯录管理系统");
    int choice;
    string name;
    string id;
    bool Changed = false;
    bool finished = false;
    Node *head = nullptr;

    while(!finished) {
        Menu();
        cin >> choice;
        switch(choice) {
            case 1:
                head = Create();                                                                // 新建学生通讯录
                break;
            case 2:
                if(head == nullptr){PLCR cout<<"【提示】:<插入失败>"<<endl;}else {
                    if (InsertStudent(head))                                                    // 向学生通讯录插入学生信息
                        cout << "插入学生信息成功!" << endl;
                    else
                        cout << "插入学生信息失败!" << endl;
                }
                break;
            case 3:                                                                             // 在通讯录删除学生信息
                if(head == nullptr){PLCR}else {
                    cout << "请输入要删除的学生通讯录信息的学号:";
                    cin >> id;
                    if (DeleteStudent(head, id))
                        cout << "删除成功!" << endl;
                    else
                        cout << "删除失败!" << endl;
                }
                break;
            case 4:                                                                             // 从文件中读取通讯录信息
                if (head = ReadFromFile())
                {
                    cout<<"【提示】:<读取成功>"<<endl;
                }else cout<<"【提示】:<读取失败>"<<endl;
                break;
            case 5:                                                                             // 向文件写入通讯录信息
                if (WriteToFile(head))
                {
                    cout<<"【提示】:<写入成功>"<<endl;
                } else{cout<<"【提示】:<写入失败>"<<endl;}
                break;
            case 6:                                                                             // 在通讯录中查询学生信息(按学号查询)
                if (head == nullptr){PLCR}else{
                    cout << "请输入要查找的学生信息的学号:";
                    cin >> id;
                    if(FSPTRID != nullptr) {
                        PrintStudentSingle(FSPTRID);
                        break;
                    }else{
                        cout << "查无此人!" << endl;
                    }
                }
                break;
            case 7:                                                                             // 在屏幕中输出全部学生信息
                if (head == nullptr){PLCR }else {
                    PrintStudent(head);
                }
                break;
            case 8:                                                                             // 修改学生信息
                if (head == nullptr){PLCR }else {
                    cout << "请输入要修改的学生信息的姓名:";
                    cin >> name;
                    if(FindStuInformation(name,head) != nullptr) {
                        Node* pTemp = FindStuInformation(name,head);
                        PrintStudentSingle(pTemp);
                        Changed = ChangeInformation(pTemp);
                        if (Changed){cout<<"修改后该生通讯录信息为:"<<endl;PrintStudentSingle(pTemp);}else cout<<"【提示】:未修改任何信息"<<endl;

                    }else{
                        cout << "查无此人!" << endl;
                    }
                }
                break;
            case 0:
                finished = true;
                break;
            default:
                system("cls");
                cout << "输入选择错误,请重新输入!" << endl;
        }
    }
}

6.3 student.h

//
// Created by Today me on 2021/6/21.
//

#ifndef STUDENT_MANGER_SYS_STUDENT_H
#define STUDENT_MANGER_SYS_STUDENT_H
#include 
#include 
#include 
#include 

#define FSPTRID FindStudent(head, id)
#define PLCR system("cls");cout<<"【提示】:<请先读取或者创建通讯录>"<<endl;
using namespace std;

struct Node {
    string id;                                // 学生的学号
    string name;                             // 姓名
    string birthday;                           // 出生日期:如1995-01-01
    int sex;                                 // 1:表示是男生,0:表示是女生
    string phone;                            // 电话
    string address;                           // 地址
    Node *next;
};

void Menu();                                 // 显示菜单函数
Node *Create();                               // 新建同学录
bool InsertStudent(Node *head);                 // 向学生通讯录插入学生信息
bool DeleteStudent(Node *head, const string& id);   // 在通讯录中删除学生信息
Node *ReadFromFile();                        // 从文件中读取通讯录信息
bool WriteToFile(Node *head);                // 向文件写入学生通讯录信息
Node * FindStudent(Node *head, const string& id); // 在通讯录中查询学生信息(按学号查询)
void PrintStudent(Node *head);                // 在屏幕中输出全部学生信息
void PrintStudentSingle(Node *pNode);       // 在屏幕中输出单个学生节点信息
Node* FindStuInformation(const string& pName, Node* pHead); // 在通讯录中查询学生信息(按姓名查询)
bool ChangeInformation(Node* pNode);          // 修改学生信息
void SYS_CONTROL();                      // 系统控制函数
void FindAll(Node* pNode,const string& pName); //打印所有符合条件的学生信息
#endif //STUDENT_MANGER_SYS_STUDENT_H

第七章 用户手册

7.1 操作步骤
7.1.1 创建通讯录
(1)按1,创建通讯录,按照提示输入学生信息,输入完成后,选择是否继续插入。
(2)按7,在屏幕中打印已有的学生信息。
(3)按6,查询已有的学生信息。
(4)按3,删除学生信息。
(5)按2,根据提示插入学生信息。
(6)按5,保存该通讯录。
(7)按8,退出系统。
7.1.2 读取通讯录
(1)按4,从文件中读取已保存的通讯录。
(2)按7,在屏幕中打印已有的学生信息。
(3)按6,查询已有的学生信息。
(4)按3,删除学生信息。
(5)按2,根据提示插入学生信息。
(6)按5,保存该通讯录。
(7)按8,退出系统。

你可能感兴趣的:(数据结构,c++,链表,数据结构,mingw,gcc/gdb编译调试)