实验要求
题目 "学生考勤管理系统设计"
1、问题描述
学生信息包括:学号、姓名、性别、年龄、班级等信息。
考勤信息包括:缺课日期、第几节课、课程名称、学生姓名、缺课类型(迟到、早退、请假和旷课)。
2、功能要求
(1)添加功能:程序能够添加学生的记录和缺课记录,提供选择界面供用户选择所要添加的类别。添加学生记录时,要求学号要唯一,如果添加了重复学号的记录时,则提示数据添加重复并取消添加。
(2)查询功能:可根据学号、姓名等信息对已添加的学生记录进行查询,如果未找到,给出相应的提示信息,如果找到,则显示相应的记录信息。还可以按课程名、学生姓名对缺课记录进行查询。
(3)显示功能:可显示当前系统中所有学生的记录和缺课记录,每条记录占据一行。
(4)编辑功能:可根据查询结果对相应的记录进行修改,修改时注意学号的唯一性。
(5)删除功能:主要实现对已添加的学生记录进行删除。如果当前系统中没有相应的记录,则提示"记录为空!"并返回操作。
(6)统计功能:能根据多种参数进行统计。能按课程名统计出学生旷课的信息、还可以按姓名统计出任一学生的旷课情况。需要排序。
(7)保存功能:可将当前系统中各类记录存入文件中,存入方式任意。
(8)读取功能:可将保存在文件中的信息读入到当前系统中,供用户进行使用。
3、问题的解决方案
根据系统功能要求,可以将问题解决分为以下步骤:
(1)应用系统分析,建立该系统的功能模块框图以及界面的组织和设计;
(2)分析系统中的各个实体及它们之间的关系;
(3)根据问题描述,设计系统的类层次;
(4)完成类层次中各个类的描述;
(5)完成类中各个成员函数的定义;
(6)完成系统的应用模块;
(7)功能调试;
(8)完成系统总结报告。
代码实验
Students.h
c++
#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
c++
#pragma once
#include"Students.h"
using namespace std;
int main()
{
init_list();
load_data();
menu();
}
Students.cpp
c++
#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查重未完全写好