C++課設-學生信息管理系統

前言:上學期的一個簡單的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;
    }

}


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章