学生考勤管理系统设计 | 李青帝

LOADING

加载过慢请开启缓存 浏览器默认开启

学生考勤管理系统设计

2024/1/15 课设 C++

实验要求

题目 “学生考勤管理系统设计

1、问题描述

学生信息包括:学号、姓名、性别、年龄、班级等信息。

考勤信息包括:缺课日期、第几节课、课程名称、学生姓名、缺课类型(迟到、早退、请假和旷课)。

2、功能要求

(1)添加功能:程序能够添加学生的记录和缺课记录,提供选择界面供用户选择所要添加的类别。添加学生记录时,要求学号要唯一,如果添加了重复学号的记录时,则提示数据添加重复并取消添加。

(2)查询功能:可根据学号、姓名等信息对已添加的学生记录进行查询,如果未找到,给出相应的提示信息,如果找到,则显示相应的记录信息。还可以按课程名、学生姓名对缺课记录进行查询。

(3)显示功能:可显示当前系统中所有学生的记录和缺课记录,每条记录占据一行。

(4)编辑功能:可根据查询结果对相应的记录进行修改,修改时注意学号的唯一性。

(5)删除功能:主要实现对已添加的学生记录进行删除。如果当前系统中没有相应的记录,则提示“记录为空!”并返回操作。

(6)统计功能:能根据多种参数进行统计。能按课程名统计出学生旷课的信息、还可以按姓名统计出任一学生的旷课情况。需要排序。

(7)保存功能:可将当前系统中各类记录存入文件中,存入方式任意。

(8)读取功能:可将保存在文件中的信息读入到当前系统中,供用户进行使用。

3、问题的解决方案

根据系统功能要求,可以将问题解决分为以下步骤:

(1)应用系统分析,建立该系统的功能模块框图以及界面的组织和设计;

(2)分析系统中的各个实体及它们之间的关系;

(3)根据问题描述,设计系统的类层次;

(4)完成类层次中各个类的描述;

(5)完成类中各个成员函数的定义;

(6)完成系统的应用模块;

(7)功能调试;

(8)完成系统总结报告。

代码实验

Students.h

#pragma once
#include<string>
#include<iostream>
#include<fstream>
#include <windows.h>
using namespace std;
typedef class Students
{
public:
    Students();
    Students(int, string, string, int, string);
    //Students(int i, string n, string s, int a, string c) :id(i), name(n), sex(s), age(a), clbum(c) {};
    void add_student();
    void show_student();
    void edit_student();
    int get_id();
protected:
    int id;//学号
    string name;//姓名
    string sex;//性别
    int age;//年龄
    string clbum;//班级
}Stu;
typedef class Attendances : public Students
{
public:
    Attendances();
    Attendances(string, string, string, string);
    Attendances(int i, string n, string s, int a, string c, string d, string p, string cc, string t) :Students(i, n, s, a, c) {
        date = d;
        period = p;
        course = cc;
        type = t;
    }
    void add_attendance();
    void show_attendance();
    string get_period();
    string get_name();
    string get_course();
    bool flag = true;
private:
    string date;//缺课日期
    string period;//第几节课
    string course;//课程名称
    string type;//缺课类型
}Att;
typedef struct Node
{
    Stu s;
    Att a;
    Node* next;
}LNode,*Linklist;
void menu();
void init_list();
void clear_buffer();
void add_student();
void add_attendance();
void query_student();
void query_attendance();
void show_all();
void edit_student();
void delete_student();
void count_absent_period();
void count_absent_name();
void save_data();
void load_data();

main.cpp

#pragma once
#include"Students.h"
using namespace std;

int main()
{
    init_list();
    load_data();
    menu();
}

Students.cpp

#pragma once
#include"Students.h"
Linklist head;
Students::Students()
{
    id = NULL;
    name = "NULL";
    sex = "NULL";
    age = NULL;
    clbum = "NULL";
}
Students::Students(int i, string n, string s, int a, string c) {
    id = i;
    name = n;
    sex = s;
    age = a;
    clbum = c;
}
Attendances::Attendances()
{
    date = "NULL";
    period = "NULL";
    course = "NULL";
    type = "NULL";
}
Attendances::Attendances(string d, string p, string c, string t)
{
    date = d;
    period = p;
    course = c;
    type = t;
}
void Students::add_student() 
{
    cout << "请输入学号:";
    cin >> id;
    cout << "\n请输入姓名:";
    cin >> name;
    cout << "\n请输入性别:";
    cin >> sex;
    cout << "\n请输入年龄:";
    cin >> age;
    cout << "\n请输入班级:";
    cin >> clbum;
    cout << endl;
}
void Students::show_student()
{
    cout << id << '\t' << name << '\t' << sex << '\t' << age << '\t' << clbum << endl;
}
void Students::edit_student()
{
    cout << "\n请输入姓名:";
    cin >> name;
    cout << "\n请输入性别:";
    cin >> sex;
    cout << "\n请输入年龄:";
    cin >> age;
    cout << "\n请输入班级:";
    cin >> clbum;
}
int Students::get_id()
{
    return id;
}
void Attendances::add_attendance()
{
    cout << "请输入缺课日期(YYYY-MM-DD):";
    cin >> date;
    cout << "\n请输入第几节课:";
    cin >> period;
    cout << "\n请输入课程名称:";
    cin >> course;
    cout << "\n请输入学生姓名:";
    cin >> name;
    cout << "\n请输入缺课类型(迟到、早退、请假、旷课):";
    cin >> type;
    cout << endl;
}
void Attendances::show_attendance()
{
    cout << date << "\t\t" << period << "\t\t" << course << "\t\t" <<name<<"\t\t" << type << endl;
}
string Attendances::get_period()
{
    return period;
}
string Attendances::get_name()
{
    return name;
}
string Attendances::get_course()
{
    return course;
}
void menu()
{
    char ch;
    while (true)
    {
        cout<<("\t\t\t\t\t***************************************")<<endl;
        cout<<("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t*|\t\t菜单\t\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t*|\t\t\b\b\b1. 添加记录\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t*|\t\t\b\b\b2. 查询记录\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t*|\t\t\b\b\b3. 显示所有记录\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t*|\t\t\b\b\b4. 编辑记录\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t*|\t\t\b\b\b5. 删除记录\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t*|\t\t\b\b\b6. 统计旷课情况\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t*|\t\t\b\b\b7. 保存数据\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t*|\t\t\b\b\b8. 加载数据\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t*|\t\t\b\b\b0. 退出程序\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
        cout<<("\t\t\t\t\t***************************************") << endl;
        cout<<("\t\t\t\t\t请选择操作:");
        ch = getchar();
        clear_buffer();
        system("cls");
        switch (ch)
        {
        case '1':
            cout << ("\t\t\t\t\t***************************************") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t请选择添加的记录类型\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\b\b\b1. 学生\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\b\b\b2. 考勤\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t***************************************") << endl;
            cout << ("\t\t\t\t\t请选择操作:");
            //cout << "请选择添加的记录类型(1-学生,2-考勤):";
            ch = getchar();
            clear_buffer();
            system("cls");
            switch (ch)
            {
            case '1':add_student(); break;
            case '2':add_attendance(); break;
            default:
                cout << "无效的选择!\n";
                break;
            }
            break;
        case '2':
            cout << ("\t\t\t\t\t***************************************") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t请选择查询的记录类型\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\b\b\b1. 学生\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\b\b\b2. 考勤\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t***************************************") << endl;
            cout << ("\t\t\t\t\t请选择操作:");
            //cout << "请选择查询的记录类型(1-学生,2-考勤):";
            ch = getchar();
            clear_buffer();
            system("cls");
            switch (ch)
            {
            case '1':query_student(); break;
            case '2':query_attendance(); break;
            default:
                cout << "无效的选择!\n";
                break;
            }
            break;
        case '3':
            show_all();
            break;
        case '4':edit_student(); break;
        case '5':delete_student(); break;
        case '6':
            cout << ("\t\t\t\t\t***************************************") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t请选择统计旷课情况的类型\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\b\b\b\b1. 按课程名称统计\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\b\b\b\b2. 按学生姓名统计\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
            cout << ("\t\t\t\t\t***************************************") << endl;
            cout << ("\t\t\t\t\t请选择操作:");
            //cout << "请选择统计旷课情况的类型(1-按课程名称统计,2-按学生姓名统计):";
            ch = getchar();
            clear_buffer();
            system("cls");
            switch (ch)
            {
            case '1':count_absent_period(); break;
            case '2':count_absent_name(); break;
            default:
                cout << "无效的选择!\n";
                break;
            }
            break;
        case '7':save_data();	cout << "保存成功!" << endl << endl; break;
        case '8':load_data(); 	cout << "加载成功!" << endl << endl; break;
        case '0':save_data(); cout << "退出成功!"<<endl; exit(0);
        default:cout << "无效的选择!\n"; exit(0);
        }
        clear_buffer();
        system("pause");
        system("cls");
    }
}
void init_list()
{
    head = new Node;
    head->next = NULL;
}
void clear_buffer()
{
    char ch;
    while ((ch = getchar()) != '\n' && ch != EOF);
}
void add_student()
{
    Linklist current,newNode = new Node;
    newNode->a.add_student();
    newNode->a.flag = false;
    newNode->next = NULL;
    while (true)
    {
        if (head->next == NULL)
        {
            head->next = newNode;
            break;
        }
        else
        {
            current = head->next;
            while (current->next != NULL)
            {
                current = current->next;
            }
            if (current->a.get_id() == newNode->a.get_id())
            {
                cout<< "学号重复!"<<endl<<endl;
                break;
            }
            current->next = newNode;
            break;
        }
    }
    save_data();
}
void add_attendance()
{
    Linklist current, newNode = new Node;
    newNode->a.add_attendance();
    newNode->next = NULL;
    if (head->next == NULL)
    {
        head->next = newNode;
    }
    else
    {
        current = head->next;
        while (current->next != NULL)
        {
            current = current->next;
        }
        current->next = newNode;
    }
    save_data();
}
void query_student()
{
    int input = 0;
    int id;
    bool flag = false;
    string name;
    Linklist current = head->next;
    cout << ("\t\t\t\t\t***************************************") << endl;
    cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t*|\t请选择该学生的查询方式\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t*|\t\t\b\b\b1. 学号\t\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t*|\t\t\b\b\b2. 姓名\t\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t***************************************") << endl;
    cout << ("\t\t\t\t\t请选择操作:");
    //cout << "请选择该学生的查询方式:(1-学号,2-姓名):";
    cin >> input;
    system("cls");
    if (input == 1)
    {
        cout << "请输入该学生的学号:";
        cin >> id;
        cout << endl << "学号" << '\t' << "姓名" << '\t' << "性别" << '\t' << "年龄" << '\t' << "班级" << endl;
        while (current != NULL)
        {
            if (current->a.flag == false&&current->a.get_id()==id)
            {
                current->a.show_student();
                flag = true;
            }
            current = current->next;
        }
        if (flag == false)
        {
            cout << endl << "记录为空!" << endl;
        }
        cout << endl;
    }
    else if (input == 2)
    {
        cout << "请输入该学生的姓名:";
        cin >> name;
        cout <<endl<< "学号" << '\t' << "姓名" << '\t' << "性别" << '\t' << "年龄" << '\t' << "班级" << endl;
        while (current != NULL)
        {
            if (current->a.flag == false && current->a.get_name() == name)
            {
                current->a.show_student();
                flag = true;
            }
            current = current->next;
        }
        if (flag == false)
        {
            cout << endl << "记录为空!" << endl;
        }
        cout << endl;
    }
    else
    {
        cout << "无效的选择!"<<endl<<endl;
    }
}
void query_attendance()
{
    int input = 0;
    bool flag = false;
    string course,name;
    Linklist current = head->next;
    cout << ("\t\t\t\t\t***************************************") << endl;
    cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t*|\t请选择该考勤的查询方式\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t*|\t\t\b\b\b1. 课程名称\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t*|\t\t\b\b\b2. 学生姓名\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t*|\t\t\t\t\t\b\b\b|*") << endl;
    cout << ("\t\t\t\t\t***************************************") << endl;
    cout << ("\t\t\t\t\t请选择操作:");
    //cout << "请选择该考勤的查询方式:(1-课程名称,2-学生姓名):";
    cin >> input;
    system("cls");
    if (input == 1)
    {
        cout << "请输入需要查询课程名称:";
        cin >> course;
        cout <<endl<< "缺课日期" << '\t' << "第几节课" << '\t' << "课程名称" << '\t' << "学生姓名" << '\t' << "缺课类型" << endl;
        while (current != NULL)
        {
            if (current->a.flag == true && current->a.get_course()==course)
            {
                current->a.show_attendance();
                flag = true;
            }
            current = current->next;
        }
        if (flag == false)
        {
            cout << endl << "记录为空!" << endl;
        }
        cout << endl;
    }
    else if (input == 2)
    {
        cout << "请输入需要查询学生姓名:";
        cin >> name;
        cout <<endl<< "缺课日期" << '\t' << "第几节课" << '\t' << "课程名称" << '\t' << "学生姓名" << '\t' << "缺课类型" << endl;
        while (current != NULL)
        {
            if (current->a.flag == true && current->a.get_name() == name)
            {
                current->a.show_attendance();
                flag = true;
            }
            current = current->next;
        }
        if (flag == false)
        {
            cout << endl << "记录为空!" << endl;
        }
        cout << endl;
    }
    else
    {
        cout << "无效的选择!" << endl<<endl;
    }
}
void show_all()
{
    Linklist current= head->next, current_2=head->next;
    cout << "\t\tStudents" << endl;
    cout << "---------------------------------------------" << endl;
    cout << "学号" << '\t' << "姓名" << '\t' << "性别" << '\t' << "年龄" << '\t' << "班级" << endl;
    while (current!=NULL)
    {
        if (current->a.flag == false)
        {
            current->a.show_student();
        }
        current = current->next;
    }
    cout << "----------------end--------------------------" << endl;
    cout << "**********************************************" << endl;
    cout << "\t\tAttendance" << endl;
    cout << "---------------------------------------------------------------------------" << endl;
    cout << "缺课日期" << '\t' << "第几节课" << '\t' << "课程名称" << '\t' << "学生姓名" << '\t' << "缺课类型" << endl;
    cout << "---------------------------------------------------------------------------" << endl;
    while (current_2 != NULL)
    {
        if (current_2->a.flag==true)
        {
            current_2->a.show_attendance();
        }
        current_2 = current_2->next;
    }
    cout << "----------------------------------end--------------------------------------" << endl;
}
void edit_student()
{
    Linklist current = head->next, current_2 = head;
    int id;
    cout << "请输入需要修改学生的学号:";
    cin >> id;
    while (current != NULL)
    {
        if (current->a.get_id()==id)
        {
            current->a.edit_student();
        }
        current = current->next;
    }
    cout << endl;
    save_data();
}
void delete_student()
{
    Linklist current = head->next;
    Linklist current_2 = head;
    int id;
    bool flag = true;
    cout << "请输入需要删除的学生学号:";
    cin >> id;
    while (current != NULL)
    {
        if (current->a.get_id() == id)
        {
            current_2->next = current->next;
            current = NULL;
            cout << endl << "删除成功!" << endl<<endl;
            flag = false;
            break;
        }
        current_2 = current;
        current = current->next;
    }
    if (flag == true)
    {
        cout << endl << "记录为空!\n" << endl;
    }
}
void count_absent_period()
{
    Linklist current = head->next, current_2 = head;
    int count = 0;
    string period;
    cout << "请输入需要统计的课程名称:";
    cin >> period;
    while (current != NULL)
    {
        if (current->a.get_period()==period)
        {
            count++;
        }
        current = current->next;
    }
    cout << endl<< period << "共有:" << count << "条记录!" << endl<<endl;
}
void count_absent_name()
{
    Linklist current = head->next, current_2 = head;
    int count = 0;
    string name;
    cout << "请输入需要统计的学生姓名:";
    cin >> name;
    while (current != NULL)
    {
        if (current->a.get_name() == name&&current->a.flag==true)
        {
            count++;
        }
        current = current->next;
    }
    cout <<endl<< name << "共有:" << count << "条记录!" << endl<<endl;
}
void save_data()
{
    fstream f("students.dat", ios::trunc|ios::out | ios::binary);
    Linklist current = head->next;
    if (!f)
    {
        cerr << "open error!" << endl;
        abort();
    }
    while (current!= NULL)
    {
        f.write(reinterpret_cast<char*>(&current->a), sizeof(current->a));
        current = current->next;
    }
    f.close();
}
void load_data()
{
    fstream f("students.dat", ios::in | ios::binary);
    if (!f)
    {
        cerr << "open error!" << endl;
        abort();
    }
    Linklist current = new Node;
    current->next = NULL;
    Linklist H = current;
    Linklist p=H;
    bool flag = true;
    while (f.read(reinterpret_cast<char*>(&current->a), sizeof(current->a))){
        flag = false;
        p->next = current;
        p = current;
        Linklist newNode = new Node;
        newNode->next = NULL;
        current->next = newNode;
        current = newNode;
    } 
    delete current;
    p->next = NULL;
    if (flag)
    {
        cout << "文件为空!";
        exit(0);
    }
    f.close();
    head->next= H;
}

注意点:必须先存入一个数据,id查重未完全写好