实验要求
题目 “学生考勤管理系统设计”
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&¤t->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&¤t->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*>(¤t->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*>(¤t->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查重未完全写好