C++课设-学生信息管理系统
前言:上学期的一个简单的C++课设项目一、问题描述:建立学生信息数据,包括学号、姓名、性别、三科成绩、出生时间、年龄(必须计算得到)。使用继承的方法构造至少3个类,(即学生类——虚基类,一年级学生和二年级学生类——派生类)使用相应的对象放置10个学生信息。编写同名display()成员函数,用来输出数组的内容。按不同类别输出学生信息,比如按性别。要求对“<<”和“>>”运算符进行重......
前言:上学期的一个简单的C++课设项目(代码在后面,附github项目链接)
一、问题描述:
建立学生信息数据,包括学号、姓名、性别、三科成绩、出生时间、年龄(必须计算得到)。
使用继承的方法构造至少3个类,(即学生类——虚基类,一年级学生和二年级学生类——派生类)使用相应的对象放置10个学生信息。
编写同名display()成员函数,用来输出数组的内容。按不同类别输出学生信息,比如按性别。要求对“<<”和“>>”运算符进行重载。
考虑到输人学号时,也会因不小心引人空格,而且名字中也需要有空格,所以重载“>>’’运算符时,需要满足这个要求。
抽取并计算学生的平均成绩。按照至少一科成绩进行排序。检索(查找)指定信息(如按姓名检索、按年龄检索)。
显示成绩分布的柱状图。
二、设计功能:
增加学生
显示全部学生
计算平均成绩
删除一个学生
按年级输出学生信息
按性别输出学生信息
按姓名检索学生
保存功能:可将当前系统中各类记录存入文件中,存入方式任意。
读取功能:可将保存在文件中的信息读入到当前系统中,供用户进行使用。
三、系统整体设计:
1.效果:
完成一个有如下功能的学生管理系统:
增加学生
显示全部学生
计算平均成绩
删除一个学生
按年级输出学生信息
按性别输出学生信息
按姓名检索学生
保存功能:可将当前系统中各类记录存入文件中,存入方式任意。
读取功能:可将保存在文件中的信息读入到当前系统中,供用户进行使用。
显示学生一科成绩的柱状图。
2.总体设计:
1)类的设计(类图见下文的类图设计):
1.选用三个主要类即基类(学生类)、派生类(一年级学生类、二年级学生类)。本系统把大部分相同功能抽取到基类,使得代码的复用成度大大提高。
除了以上三类本系统为了方面使用和管理一些数据。建立了成绩类(包括语文、数学、英语成绩),和出生日期类(年月日),并将它们的属性公开。
2.重载了运算符“<<”和“>>”
使得学生类的输入和输出比较方便。重载代码见Stu.cpp
2)类图
3)基本功能的实现:
1.本系统选用C++的STL库的map和vector作为基本功能实现的基础。其中map为学生id(键)和学生对象(值)的一对一映射。选用map的原因是map不允许存在两个一样键,可以防止学号重复的错误。选用键值对的存储方式也便于查找。选用vector作为排序的容器来实现按成绩排序的功能,排序所需的比较函数为自己定义的函数。可见main.cpp中的Compare()函数。
3查找,删除,增加,计算平均成绩等功能均围绕map来进行。增加即利用重载的“>>”输入之后利用map的insert函数插入。删除利用map的erse函数删除。查找的话,如果是按名字查找就利用迭代器遍历map比较名字是否相同(其他查找类同),如果相同就用“<<”输出。计算平均成绩用遍历的方法遍历进行求和和求平均数就可以了。
4.年龄的计算,在学生类中增加了一个成员函数。用于计算年龄。年龄的计算法则:使用C++的tm类获取当前的年月日。通过年月日的比较计算学生当前的年龄。
4.保存和读取文件:本系统使用二进制文件存取数据。直接把map中的学生对象保存到文件中。当程序启动时又从文件中依次读取数据,把学生对象存到map中来。
5.数学成绩的柱状图
由于不会C++的作图。于是用循环和字符输出。用了两个循环。统计0~90,90~100,100~120,120~130,130~150 5个分数段的人数,并画图。
四、系统调试
1.调试结果:
1)系统目录
2)添加学生
3)删除学生
4)显示所有学生的信息
5)按年级分别输出学生信息
6)按性别输出学生
7)按姓名检索学生
8)按学号检索学生
9)学生的平均成绩
10)按数学学科成绩排序
11)按数学成绩的分布的柱状图:
2.调试过程遇到的问题以及解决方法:
1)调试中遇到最大的问题是把string类型写入二进制文件时,再读出来就是乱码了。
一开始以为时编译器编码格式设置的问题,后来尝试多次无果之后。尝试把string改成char[20]就行了。究其原因string保存的是指向char*的地址,所以会出问题。、
2)要求重载运算符能输入空格。经过查询,采用了
istream的getline()方法。采取这种
is.getline(temp,20,'\n');
方法即可。设置了’\n’为结束符。
五、源代码
项目结构(IDE环境:Code::blocks):
Stu.h
#ifndef STU_H
#define STU_H
#include <string>
#include <iostream>
#include <istream>
#include <stdlib.h>
#include <cstring>
#include <ctime>
using namespace std;
class BirthTime{
public:
int year;
int month;
int day;
};
class Grade{
public:
float math_grade;
float Enlish_grade;
float Chinese_grade;
};
class Stu
{
public:
Stu(unsigned int Stu_id,string name,string sex,BirthTime birthtime,Grade g);
Stu();
unsigned int Get_Id();
void Set_id(unsigned int id);
string Get_name();
void Set_name(string name);
string Get_sex();
void Set_sex(string sex);
BirthTime Get_BirthTime();
void Set_BirthTime(BirthTime b);
int Get_Type();
void Set_Type(int type);
int Caculate_Age();
void Set_Grade(Grade g);
Grade Get_Grade();
friend istream & operator>>(istream &is,Stu &stu);
friend ostream & operator<<(ostream &os,Stu &stu);
private:
long int stu_id;
string name;
string sex;
BirthTime birthtime;
Grade grade;
int type;
};
#endif // STU_H
Stu_one.h
#ifndef STU_ONE_H
#define STU_ONE_H
#include "Stu.h"
class Stu_one:public Stu
{
public:
Stu_one(int stu_id,string name,string sex,BirthTime birthtime,Grade g);
Stu_one();
};
#endif // STU_ONE_H
Stu_two.h
#ifndef STU_TWO_H
#define STU_TWO_H
#include "Stu.h"
class Stu_two:public Stu
{
public:
Stu_two(int stu_id,string name,string sex,BirthTime birthtime,Grade g);
Stu_two();
};
#endif // STU_TWO_H
Stu.cpp
#include "Stu.h"
Stu::Stu(){
}
void Stu::Set_Grade(Grade g){
this->grade=g;
}
Grade Stu::Get_Grade(){
return this->grade;
}
Stu::Stu(unsigned int stu_id,string name,string sex,BirthTime birthtime,Grade g){
this->stu_id=stu_id;
this->name=name;
this->sex=sex;
this->birthtime=birthtime;
this->grade=g;
}
unsigned int Stu::Get_Id(){
return this->stu_id;
}
void Stu::Set_id(unsigned int id){
this->stu_id=id;
}
string Stu::Get_name(){
return this->name;
}
void Stu::Set_name(string name){
this->name=name;
}
string Stu::Get_sex(){
return this->sex;
}
void Stu::Set_sex(string sex){
this->sex=sex;
}
BirthTime Stu::Get_BirthTime(){
return this->birthtime;
}
void Stu::Set_BirthTime(BirthTime b){
this->birthtime=b;
}
int Stu::Get_Type(){
return this->type;
}
void Stu::Set_Type(int type){
this->type=type;
}
int Stu::Caculate_Age(){
// 基于当前系统的当前日期/时间
time_t now = time(NULL);
// 把 now 转换为 tm 结构
tm *gmtm = gmtime(&now);
int age=0;
int year_now=gmtm->tm_year+1900;
int birth_month=this->birthtime.month;
if(gmtm->tm_mon>=birth_month&&gmtm->tm_yday>=this->birthtime.day){
age=year_now-this->birthtime.year;
}else{
age=year_now-this->birthtime.year-1;
}
return age;
}
istream & operator>>(istream &is,Stu &stu)
{
char temp[50];
is.getline(temp,50,'\n');
BirthTime time;
Grade grade;
cout<<"请输入学号:(10位)"<<endl;
is.getline(temp,50,'\n');
stu.Set_id(atoi(temp));
cout<<"请输入姓名:"<<endl;
is.getline(temp,20,'\n');
stu.Set_name(temp);
cout<<"请输入性别(男/女):"<<endl;
is.getline(temp,10);
if(!strcmp(temp,"男")||!strcmp(temp,"女")){
//true
}else{
cout<<"输入性别不正确!"<<endl;
}
stu.Set_sex(temp);
cout<<"请输入出生时间:"<<endl;
cout<<"请输入出生年份:"<<endl;
is.getline(temp,10,'\n');
time.year=atoi(temp);
cout<<"请输入出生月份:"<<endl;
is.getline(temp,10);
time.month=atoi(temp);
cout<<"请输入出生日期:"<<endl;
is.getline(temp,10,'\n');
time.day=atoi(temp);
stu.Set_BirthTime(time);
cout<<"科目成绩:"<<endl;
cout<<"输入语文成绩:"<<endl;
is.getline(temp,10,'\n');
grade.Chinese_grade=atof(temp);
cout<<"输入数学成绩:"<<endl;
is.getline(temp,10,'\n');
grade.math_grade=atof(temp);
cout<<"输入英语成绩:"<<endl;
is.getline(temp,10,'\n');
grade.Enlish_grade=atof(temp);
stu.Set_Grade(grade);
return is;
}
ostream & operator<<(ostream &os,Stu &stu)
{
os<<"学生-基本信息:"<<endl;
os<<"--------------------"<<endl;
os<<"学号:"<<stu.Get_Id()<<endl;
os<<"姓名:"<<stu.Get_name()<<endl;
os<<"性别:"<<stu.Get_sex()<<endl;
os<<"年龄:"<<stu.Caculate_Age()<<endl;
os<<"年级:"<<stu.Get_Type()<<endl;
os<<"--------------------"<<endl;
os<<"学生-成绩表"<<endl;
os<<"语文:"<<stu.Get_Grade().Chinese_grade<<endl;
os<<"数学:"<<stu.Get_Grade().math_grade<<endl;
os<<"英语:"<<stu.Get_Grade().Enlish_grade<<endl;
os<<"--------------------"<<endl;
return os;
}
Stu_one.cpp
#include "Stu_one.h"
Stu_one::Stu_one(int stu_id,string name,string sex,BirthTime birthtime,Grade g):Stu(stu_id,name,sex,birthtime,g){
Set_Type(1);
}
Stu_one::Stu_one(){
Set_Type(1);
}
Stu_two.cpp
#include "Stu_two.h"
Stu_two::Stu_two(int stu_id,string name,string sex,BirthTime birthtime,Grade g):Stu(stu_id,name,sex,birthtime,g){
Set_Type(2);
}
Stu_two::Stu_two(){
Set_Type(2);
}
main.cpp
#include "Stu_one.h"
#include "Stu_two.h"
#include <map>
#include <fstream>
using namespace std;
map<int,Stu> Stu_map;
void Reload();//加载当前所有记录
void SaveRecord();//保存当前所有记录
void Add_Stu();//添加学生模块
void Delete_Stu();//删除学生模块
void Traverse_Stu();//遍历所有学生
int main()
{
int chioce=0;
while(1){
cout<<"--------------------------------学生管理系统----------------------------------------" << endl;
cout<<"1.添加学生"<<endl;
cout<<"2.删除学生"<<endl;
cout<<"3.按年级输出学生信息"<<endl;
cout<<"4.按性别输出学生信息"<<endl;
cout<<"5.按姓名检索学生"<<endl;
cout<<"6.输出学生的成绩情况"<<endl;
cout<<"7.显示全部学生"<<endl;
cout<<"8.保存当前记录"<<endl;
cout<<"9.从文件中读取数据"<<endl;
cout<<"请输入你的选择:"<<endl;
cin>>chioce;
switch(chioce){
case 1:
Add_Stu();
break;
case 2:
Delete_Stu();
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
Traverse_Stu();
case 8:
SaveRecord();
break;
case 9:
Reload();
}
}
return 0;
}
//加载记录
void Reload(){
ifstream savefile("save.txt",ios::in | ios::binary);
string name;
Stu stu;
int b=0;
while(savefile.eof()!=1) {
savefile.read((char *)&stu,sizeof(Stu));
Stu_map.insert(map<int, Stu>::value_type (stu.Get_Id(), stu));
}
savefile.close();
}
//保存记录
void SaveRecord(){
ofstream savefile("save.txt",ios::out | ios::binary );
map<int, Stu>::iterator iter;
iter = Stu_map.begin();
string name;
while(iter != Stu_map.end()) {
Stu stu=(Stu)iter->second;
savefile.write((char*)&(stu),sizeof(Stu));
iter++;
}
savefile.close();
}
//遍历
void Traverse_Stu(){
map<int, Stu>::iterator iter;
iter = Stu_map.begin();
while(iter != Stu_map.end()) {
cout<<iter->second<<endl;
iter++;
}
}
//删除
void Delete_Stu(){
int id=0;
cout<<"请输入欲删除学生的学号:"<<endl;
cin>>id;
if(id!=0){
Stu_map.erase(id);
}
}
//添加
void Add_Stu(){//添加学生模块
int chioce=0;
cout<<"1.添加1年级学生"<<endl;
cout<<"2.添加2年级学生"<<endl;
cout<<"3.请输入你的选择: "<<endl;
cin>>chioce;
switch(chioce){
case 1:
{
Stu_one stu;
cin>>stu;
Stu_map.insert(map<int, Stu>::value_type (stu.Get_Id(), stu));
}
break;
case 2:
{
Stu_two stu;
cin>>stu;
Stu_map.insert(map<int, Stu>::value_type (stu.Get_Id(), stu));
}
break;
}
}
Github地址:https://github.com/DhyanaCoder/StudentManagerSystem
更多推荐
所有评论(0)