「数据结构上机作业1」学生成绩管理系统

「数据结构上机作业1」学生成绩管理系统

hash070 384 2022-03-05

利用链表实现一个简单的学生成绩管理系统:

(1)学生成绩信息包括学号、姓名、性别、班级、高等数学成绩、大学英语成绩、C语言程序设计成绩和软件工程导论成绩等;

(2)系统的主要功能包括:学生成绩信息的创建、输出学生成绩信息、查询学生成绩、增加学生成绩、删除学生成绩。

软件设计

本程序使用C来编写,首先引入头文件(bits/stdc.h或isotream),并声明使用的命名空间

//#include <bits/stdc++.h>
#include <iostream>
using namespace std;

学生信息结构体

不论是使用结构体还是数组来管理学生信息,结构体都能让数据的管理更加方便和高效。

struct Stu {//学生信息结构体
    string sno;//学号
    string name;//姓名
    int gender;//性别,0女1男
    string grade;//年级
    int math;//数学成绩
    int eng;//英语成绩
    int clang;//C语言成绩
    int se;//软件工程导论成绩
};

链表/线性表结构设计

本次作业要求使用线性表来实现对学生信息的操作,下面是有关链表定义的代码

struct StuList {//学生信息链表
    Stu student;//数据部分
    StuList *next;//指针部分
public://预先声明一些相关的函数
    void createStuList(int n);//结构体的构造函数
    void addStu(int n);//添加学生的方法
    void delStu(string n);//删除指定学生的方法
    void findStu(string n);//查询输出学生信息
    void listStu();//列出所有学生
    static void printStu(StuList *ptr);//打印学生信息的方法
};

结构体方法设计

void StuList::createStuList(int n) {
    StuList *pnew, *ptemp;
    ptemp = this;//从本节点开始创建
    if (n < 0) {       //当输入的值有误时,处理异常
        cout << "输入的节点个数有误" << endl;
        exit(EXIT_FAILURE);
    }
    for (int i = 0; i < n; i++) {        //将值一个一个插入单链表中
        pnew = new StuList;
        cout << "请输入第" << i + 1 << "个值: " << endl;
        int inputInt = 0;
        string inputStr;
        reInputStuInfo1://重新输入学生信息的标签
        try {
            cout << "请输入学生信息:" << endl;
            cout << "请输入4位学号:";
            cin >> inputStr;
            if (inputStr.length() != 4)//获得并验证学号长度
                throw "学号长度输入错误";
            pnew->student.sno = inputStr;
            cout << "请输入姓名:";
            cin >> pnew->student.name;
            cout << "请输入性别(0女1男):";
            cin >> inputInt;
            if (inputInt != 0 && inputInt != 1)//获得并验证性别
                throw "性别输入错误";
            pnew->student.gender = inputInt;
            cout << "请输入年级:";
            cin >> pnew->student.grade;
            cout << "请输入数学成绩:";
            cin >> inputInt;
            if (!(inputInt >= 0 && inputInt <= 100))//获得并验证成绩
                throw "成绩输入错误";
            pnew->student.math = inputInt;
            cout << "请输入英语成绩:";
            cin >> inputInt;
            if (!(inputInt >= 0 && inputInt <= 100))//获得并验证成绩
                throw "成绩输入错误";
            pnew->student.eng = inputInt;
            cout << "请输入C语言成绩:";
            cin >> inputInt;
            if (!(inputInt >= 0 && inputInt <= 100))//获得并验证成绩
                throw "成绩输入错误";
            pnew->student.clang = inputInt;
            cout << "请输入软件工程导论成绩:";
            cin >> inputInt;
            if (!(inputInt >= 0 && inputInt <= 100))//获得并验证成绩
                throw "成绩输入错误";
            pnew->student.se = inputInt;
        } catch (const char *e) {
            cout << e << ",请重新输入" << endl;
            goto reInputStuInfo1;//返回到输入代码
        }
        cout << "成绩输入完成" << endl;
        pnew->next = nullptr;          //新节点的下一个地址为NULL
        ptemp->next = pnew;         //当前结点的下一个地址设为新节点
        ptemp = pnew;               //将当前结点设为新节点
    }
}

void StuList::addStu(int n) {
    StuList *pnew, *ptemp;
    ptemp = this;
    while (ptemp->next != nullptr)//当移动到指针所指的next指向空时,意味着到了末尾
        ptemp = ptemp->next;
    if (n < 0) {       //当输入的值有误时,处理异常
        cout << "输入的节点个数有误" << endl;
        exit(EXIT_FAILURE);
    }
    for (int i = 0; i < n; i++) {        //将值一个一个插入单链表中
        pnew = new StuList;
        cout << "请输入第" << i + 1 << "个值: " << endl;
        int inputInt = 0;
        string inputStr;
        reInputStuInfo2://重新输入学生信息的标签
        try {
            cout << "请输入学生信息:" << endl;
            cout << "请输入4位学号:";
            cin >> inputStr;
            if (inputStr.length() != 4)//获得并验证学号长度
                throw "学号长度输入错误";
            pnew->student.sno = inputStr;
            cout << "请输入姓名:";
            cin >> pnew->student.name;
            cout << "请输入性别(0女1男):";
            cin >> inputInt;
            if (inputInt != 0 && inputInt != 1)//获得并验证性别
                throw "性别输入错误";
            pnew->student.gender = inputInt;
            cout << "请输入年级:";
            cin >> pnew->student.grade;
            cout << "请输入数学成绩:";
            cin >> inputInt;
            if (!(inputInt >= 0 && inputInt <= 100))//获得并验证成绩
                throw "成绩输入错误";
            pnew->student.math = inputInt;
            cout << "请输入英语成绩:";
            cin >> inputInt;
            if (!(inputInt >= 0 && inputInt <= 100))//获得并验证成绩
                throw "成绩输入错误";
            pnew->student.eng = inputInt;
            cout << "请输入C语言成绩:";
            cin >> inputInt;
            if (!(inputInt >= 0 && inputInt <= 100))//获得并验证成绩
                throw "成绩输入错误";
            pnew->student.clang = inputInt;
            cout << "请输入软件工程导论成绩:";
            cin >> inputInt;
            if (!(inputInt >= 0 && inputInt <= 100))//获得并验证成绩
                throw "成绩输入错误";
            pnew->student.se = inputInt;
        } catch (const char *e) {
            cout << e << ",请重新输入" << endl;
            goto reInputStuInfo2;//返回到输入代码
        }
        cout << "成绩输入完成" << endl;
        pnew->next = nullptr;          //新节点的下一个地址为NULL
        ptemp->next = pnew;         //将刚创建的结点的下一个地址设为新节点
        ptemp = pnew;               //ptemp指针指向新节点
    }
}

void StuList::listStu() {
    StuList *ptr = this;
    ptr = ptr->next;//先移动一位避开头结点
    while (ptr != nullptr) {//按照这样的循环条件,在最后一个循环中这个指针将变成空指针,但不影响输出
        printStu(ptr);
        ptr = ptr->next;
    }
}

void StuList::printStu(StuList *ptr) {
    string gen;
    cout << "学生姓名:" << ptr->student.name << endl;
    cout << "学生学号:" << ptr->student.sno << endl;
    if (ptr->student.gender)
        gen = "男生";
    else
        gen = "女生";
    cout << "学生性别:" << gen << endl;
    cout << "学生年级:" << ptr->student.grade << endl;
    cout << "数学成绩:" << ptr->student.math << endl;
    cout << "英语成绩:" << ptr->student.eng << endl;
    cout << "C语言成绩:" << ptr->student.clang << endl;
    cout << "软件工程导论成绩:" << ptr->student.se << endl;
}

void StuList::delStu(string n) {//这里的n指的是学号
    StuList *ptr = this;
    StuList *ptemp;
    while (ptr != nullptr) {
        if (ptr->student.sno == n) {//如果找到相应的学号
            string name = ptr->student.name;
            ptemp->next = ptr->next;//让前面的节点的next指针指向这个节点的next方向
            delete ptr;
            cout << name << "的学生信息" << "已删除" << endl;
            return;
        }
        ptemp = ptr;//ptemp指针将永远比ptr慢一步
        ptr = ptr->next;
    }
    cout << "没有找到学号为" << n << "的学生" << endl;
}

void StuList::findStu(string n) {
    StuList *ptr = this;
    ptr = ptr->next;//避开无数据的头结点
    while (ptr != nullptr) {
        if (ptr->student.sno == n) {//如果找到相应的学号
            cout << "找到该学生" << endl;
            printStu(ptr);
            return;
        }
        ptr = ptr->next;
    }
    cout << "没有找到学号为" << n << "的学生" << endl;
}

main函数设计

int main() {
    StuList s;
    int o;
    string sno;
    cout << "创建链表时要输入几个学生信息?" << endl;
    cin >> o;
    s.createStuList(o);
    while (true) {
        cout << "====请输入要执行的命令====" << endl;
        cout << "====1.输出学生成绩信息====" << endl;
        cout << "====2.查询学生成绩信息====" << endl;
        cout << "====3.增加学生信息====" << endl;
        cout << "====4.删除学生信息====" << endl;
        cout << "====5.退出====" << endl;
        cin >> o;
        switch (o) {
            case 1:
                s.listStu();
                break;
            case 2:
                cout << "要查找的学号:";
                cin >> sno;
                s.findStu(sno);
                break;
            case 3:
                cout << "增加的学生的数量:";
                cin >> o;
                s.addStu(o);
                break;
            case 4:
                cout << "要删除的学生的学号:";
                cin >> sno;
                s.delStu(sno);
                break;
            case 5:
                cout << "程序退出" << endl;
                return 0;
            default:
                cout << "输入错误,请重新输入" << endl;
        }
    }
}

测试结果

创建链表时要输入几个学生信息?
2
请输入第1个值: 
请输入学生信息:
请输入4位学号:1111
请输入姓名:1
请输入性别(0女1男):1
请输入年级:1
请输入数学成绩:1
请输入英语成绩:1
请输入C语言成绩:1
请输入软件工程导论成绩:1
成绩输入完成
请输入第2个值: 
请输入学生信息:
请输入4位学号:2222
请输入姓名:2
请输入性别(0女1男):2
性别输入错误,请重新输入
请输入学生信息:
请输入4位学号:2222
请输入姓名:1
请输入性别(0女1男):1
请输入年级:22
请输入数学成绩:2
请输入英语成绩:2
请输入C语言成绩:2
请输入软件工程导论成绩:2
成绩输入完成
====请输入要执行的命令====
====1.输出学生成绩信息====
====2.查询学生成绩信息====
====3.增加学生信息====
====4.删除学生信息====
====5.退出====
1
学生姓名:1
学生学号:1111
学生性别:男生
学生年级:1
数学成绩:1
英语成绩:1
C语言成绩:1
软件工程导论成绩:1
学生姓名:1
学生学号:2222
学生性别:男生
学生年级:22
数学成绩:2
英语成绩:2
C语言成绩:2
软件工程导论成绩:2
====请输入要执行的命令====
====1.输出学生成绩信息====
====2.查询学生成绩信息====
====3.增加学生信息====
====4.删除学生信息====
====5.退出====
2
要查找的学号:2222
找到该学生
学生姓名:1
学生学号:2222
学生性别:男生
学生年级:22
数学成绩:2
英语成绩:2
C语言成绩:2
软件工程导论成绩:2
====请输入要执行的命令====
====1.输出学生成绩信息====
====2.查询学生成绩信息====
====3.增加学生信息====
====4.删除学生信息====
====5.退出====
3
增加的学生的数量:2
请输入第1个值: 
请输入学生信息:
请输入4位学号:3333
请输入姓名:3
请输入性别(0女1男):1
请输入年级:333
请输入数学成绩:3
请输入英语成绩:3
请输入C语言成绩:3
请输入软件工程导论成绩:3
成绩输入完成
请输入第2个值: 
请输入学生信息:
请输入4位学号:4444
请输入姓名:4
请输入性别(0女1男):1
请输入年级:4
请输入数学成绩:4
请输入英语成绩:4
请输入C语言成绩:4
请输入软件工程导论成绩:4
成绩输入完成
====请输入要执行的命令====
====1.输出学生成绩信息====
====2.查询学生成绩信息====
====3.增加学生信息====
====4.删除学生信息====
====5.退出====
2
要查找的学号:4444
找到该学生
学生姓名:4
学生学号:4444
学生性别:男生
学生年级:4
数学成绩:4
英语成绩:4
C语言成绩:4
软件工程导论成绩:4
====请输入要执行的命令====
====1.输出学生成绩信息====
====2.查询学生成绩信息====
====3.增加学生信息====
====4.删除学生信息====
====5.退出====
1
学生姓名:1
学生学号:1111
学生性别:男生
学生年级:1
数学成绩:1
英语成绩:1
C语言成绩:1
软件工程导论成绩:1
学生姓名:1
学生学号:2222
学生性别:男生
学生年级:22
数学成绩:2
英语成绩:2
C语言成绩:2
软件工程导论成绩:2
学生姓名:3
学生学号:3333
学生性别:男生
学生年级:333
数学成绩:3
英语成绩:3
C语言成绩:3
软件工程导论成绩:3
学生姓名:4
学生学号:4444
学生性别:男生
学生年级:4
数学成绩:4
英语成绩:4
C语言成绩:4
软件工程导论成绩:4
====请输入要执行的命令====
====1.输出学生成绩信息====
====2.查询学生成绩信息====
====3.增加学生信息====
====4.删除学生信息====
====5.退出====
4
要删除的学生的学号:2222
1的学生信息已删除
====请输入要执行的命令====
====1.输出学生成绩信息====
====2.查询学生成绩信息====
====3.增加学生信息====
====4.删除学生信息====
====5.退出====
1
学生姓名:1
学生学号:1111
学生性别:男生
学生年级:1
数学成绩:1
英语成绩:1
C语言成绩:1
软件工程导论成绩:1
学生姓名:3
学生学号:3333
学生性别:男生
学生年级:333
数学成绩:3
英语成绩:3
C语言成绩:3
软件工程导论成绩:3
学生姓名:4
学生学号:4444
学生性别:男生
学生年级:4
数学成绩:4
英语成绩:4
C语言成绩:4
软件工程导论成绩:4
====请输入要执行的命令====
====1.输出学生成绩信息====
====2.查询学生成绩信息====
====3.增加学生信息====
====4.删除学生信息====
====5.退出====
5
程序退出

进程已结束,退出代码0