实验设计的题目、内容
研究生考试课程为4门,其中数学、外语、政治为统一命题,而专业基础课则根据不同的专业由招生学校自行命题。国家对初试录取分数有总分要求(如某一年要求4门课总分应达到310分),另外还有对每门课的最低分数要求(如总分为100的试卷最低应达到40分,总分为150的试卷最低应达到65分)
研究生初试录取系统(LMS)在Devc++平台下开发,操作系统:Windows 10。
硬件环境:
处理器:Intel(R) Core(TM) i5-8265M CPU @ 1.60GHz 1.80GHz
内存:8.00GB
系统类型:64位操作系统
编程统计初试合格的人数,并按总分由高到低的顺序输出合格考生的信息。具体功能:(1)程序运行时首先要求输入:考生姓名,准考证号,报考专业,是否应届生,4门课(政治、数学、外语、专业基础课)成绩。同时,这些原始数据应保存到一个文件中。(2)然后输入:录取的总分要求,各课程的最低分数要求。(3)输出要求:过线考生的姓名,准考证号,报考专业,是否应届生,4门课程(政治、数学、外语、专业基础课)成绩及总分,这些信息应存放到另一个文件中。(4)测试数据。
3.2.1研究生初试录取系统的主要功能为:
3.修改学生信息 4.删除学生信息
5.输入过线标准并输出合格学生 6.查询删改记录
下图为该系统的功能分解
系统各模块的功能具体描述为:
1、查询操作
输入你想查询的学生的学号(学号唯一并且只能通过学号查找)
系统依次输出该学生的姓名、学号、专业、是否应届生、政治成绩、数学成绩、英语成绩、专业成绩及总分。按“1”返回主菜单,按“2”退出系统。
2、添加操作
可以先输入添加的人数,再输入这些学生的具体信息(界面会给出各个信息的输入顺序,注意一定要按顺序输入),系统把这些数据写入到一个文本中。最后返回菜单。
3、修改操作
可以根据输入的学生学号先查询出该学生的原本信息,再按顺序输入修改后的信息(注意学号唯一且不可修改)系统在把新数据读入到文本中。若在这过程中,学号前后不一致的话,系统自动提醒,并要重新输入。
4、删除学生信息操作
先输入你要删除学生的学号,系统从文本中读到该学号的学生信息,并将其删除,再重新更新文本。同时,将删除的学生信息存到另一个文本中。
5、输入过线标准并且输出过线学生
按科成绩及总分的过线标准,系统从存储学生信息的文件中读取信息,并进行判断,当学号相同时,将该学生的信息存入到另一个文本中,同时排序输出结果。
6、查询删除信息
读取存储删除的学生信息的文本,界面输出结果。
系统涉及对象有两个基本类:学生类和过线要求类。
1)学生类,包含s_name学生姓名、s_id学号、s_major专业、isfresh是否为应届生、scoreMath 数学成绩、scoreEnglish英语成绩、scorePolitic政治成绩、scoreMajor专业课成绩、total总分。
类的声明及定义如下:
#ifndef STUDENT_H
#define STUDENT_H
#include
#include
#include
using std::string;
using std::cin;
using std::setw;
class student{
private:
string s_name;
string s_id;
string s_major;
string isfresh;
int scoreMath;
int scoreEnglish;
int scorePolitic;
int scoreMajor;
int total ;
public:
student( student &s){//构造函数
setname(s.getname());
setid(s.getid());
setMajor(s.getMajor());
setisf(s.getisf() );
setMath(s.getMath());
setEnglish(s.getEnglish());
setPolitic(s.getPolitic());
setmajor(s.getmajor());
settotal();
}
student(){}
student(const string& na,const string &id,const string& maj,const string& isf,
const int& politic,const int& math,const int& english,const int& major);
void setMath(int x){scoreMath=x;}//设置或修改数学成绩
void setEnglish(int x ){scoreEnglish=x;}//设置或修改英语成绩
void setPolitic(int x){scorePolitic=x;}//设置或修改政治成绩
void setMajor(int x){ scoreMajor=x;}//设置或修改专业成绩
void setname(string na){s_name=na;}//设置或修改学生姓名
void setid(string id){s_id=id; }//设置学生学号
void setmajor(string maj){ s_major=maj;}//设置或修改学生专业
void setisf(string isf){isfresh=isf;//设置或修改学生是否为应届生
}
void settotal(){
total=scoreMath+scorePolitic+scoreMajor+scoreEnglish;
}
string getname(){//获取姓名
return s_name;
}
string getid(){//获取学号
return s_id;}
string getmajor(){//获取专业
return s_major;}
string getisf(){//获取是否为应届生
return isfresh;}
int getMath(){return scoreMath;//获取数学成绩
}
int getEnglish(){return scoreEnglish; //获取英语成绩
}
int getMajor(){return scoreMajor;//获取专业成绩
}
int getPolitic(){return scorePolitic;//获取政治成绩
}
int getsumscore(){return scoreMath+scoreEnglish+scoreMajor+scorePolitic; } //获取总分成绩
bool ispassed(const int& po, const int& ma,const int& en, const int& maj,const int& tot);//判断是否过线
void setall(const string& na,const string &id,const string& maj,const string& isf,
const int& politic,const int& math,const int& english,const int& major);
friend std::istream& operator>> (std::istream &, student& );//输入函数
friend std::ostream& operator<< (std::ostream &, student& );//输出函数
};
#endif // STUDENT_H
2)过线要求类的编写
require中含五个数据,分别是po政治成绩、ma数学成绩、en英语成绩、maj专业成绩、tot总分成绩。
class require{
private:
int po;
int ma;
int en;
int maj;
int tot;
public:
require(int p,int m,int e,int n,int t):po(p),ma(m),en(e),maj(n),tot(t){}//构造函数
require(){
}
int getpo(){//获取政治成绩过线要求
return po;
}
int getma(){//获取数学成绩过线要求
return ma;}
int geten(){//获取英语成绩过线要求
return en ;
}
int getmaj(){//获取专业成绩过线要求
return maj;
}
int gettot(){//获取总分成绩过线要求
return tot;
}
friend std::istream& operator >> (std::istream &input, require& a)
{ input >> a.po >> a.ma >> a.en >> a.maj
>> a.tot;
return input;}
};
制定过线要求及按总分从高到低输出过线学生信息的流程图如下 (涉及到两个类的操作)
4.1查询函数chaxun()
stut (存储学生信息)
菜单界面如下
接下来输入该学生的学号
输出该学生的完整信息 按“1”返回菜单。
4.2
add()函数增加学生信息
接下里输入该学生的信息
图 写入具体学生信息的界面
图 存储学生信息的文本发生变化
4.3修改 change()函数
依次输入修改后的数据
stut.txt截图
4.4删除函数deletes()
4.5制定过线标准并输出过线学生
输入这五个要求
4.6删除数据的截图
系统在调试测试过程中遇到若干问题,不过经过仔细反复的检查已经消除各种bug。
遇到的问题及解决方法如下:
5.1.1
问题具体描述:在查询及涉及到读文本的工作时,只能读入第一个数据,所以任何操作都只有第一行有效,查询时只有查第一个才能正常输出,其他系统都提示“该学生找不到”。
5.1.2
问题产生的具体原因:在输出一个学生类的所有信息时,本意是想让只要输入四门课的成绩,总成绩自动计算,不需要手动输入,所以我以前写的类的输入输出函数如下图
但在读写操作时,系统默认这两个类型是不匹配的,因此,读完第一行,系统就会检测不到匹配的类型,便不会继续读下去,这样就导致了这个错误结果。
5.1.3 解决方法
检重新改写类的输入函数,使总分从自动计算,改为手动输入。这样两个类型就匹配了,但是缺点是无法判断总分的正确性,手动输入错误率较高。
图 修改后的输入函数
5.2.1问题具体描述
读取文件时最后一行总是会多读一次,输出了两条一模一样的信息,使系统部分功能不能正常运行。
5.2.2 问题产生具体原因
存储的时候,文件最后是换行,仅有eof函数来判断是不行的。
5.2.3问题解决办法
再增加一个条件,最后的时候先判断是否结束,再退出循环
我设计的研究生初试录取系统基本满足任务书的功能要求,类的结构和关系清晰,功能完善,能够比较粗略地实现所要求的功能。
存在的主要缺点:第一,没有使用链表,用动态数组来存放临时信息,可能在时间和空间上有一定的消耗;第二个最主要的缺点是,无法判断学生信息是否学号重合、总分是否正确,因为涉及到频繁的读写记录操作。并且我设计的系统把学号当做主键,只能通过学号来查找,这样的代码在实际生活中是及其单薄,甚至是漏洞百出的。
通过这次C++的大型实验,我深刻的明白到:课本知识与实践能力相结合的重要性。上课听得懂不代表真的会打代码了,虽然老师平时给我们的练习题目偏简单,我们也不应该放低对自己的要求,应当脚踏实地,一步步落实,把学到的知识转化为自己的。写代码的过程中,会出现非常非常多的错误,很大一部分原因是平时练习的太少了,实践能力太薄弱了,一写代码便错误百出。编译器只是机械的执行我们所给的指令,纵然代码语法上没有问题了,逻辑硬伤也会使得错误的结果产生,只有理清代码的逻辑关系,耐心编写修改,才能使得系统正常运行。这次的实验课让我熟悉了文件读写等等操作,这些都是我上课并不是很理解的知识,但通过这次实验,我熟悉了这学期学过的操作的使用方法,落实了上课的知识。只有将理论运用到实践中去,你才能深刻地理解这个理论,并在他的基础上举一反三。
源码
student.h
#ifndef STUDENT_H
#define STUDENT_H
#include
#include
#include
using std::string;
using std::cin;
using std::setw;
class student{
private:
string s_name;
string s_id;
string s_major;
string isfresh;
int scoreMath;
int scoreEnglish;
int scorePolitic;
int scoreMajor;
int total ;
public:
student( student &s){
setname(s.getname());
setid(s.getid());
setMajor(s.getMajor());
setisf(s.getisf() );
setMath(s.getMath());
setEnglish(s.getEnglish());
setPolitic(s.getPolitic());
setmajor(s.getmajor());
settotal();
}
student(){}
student(const string& na,const string &id,const string& maj,const string& isf,
const int& politic,const int& math,const int& english,const int& major);
void setMath(int x){scoreMath=x;}
void setEnglish(int x ){scoreEnglish=x;}
void setPolitic(int x){scorePolitic=x;}
void setMajor(int x){ scoreMajor=x;}
void setname(string na){s_name=na;}
void setid(string id){s_id=id; }
void setmajor(string maj){ s_major=maj;}
void setisf(string isf){isfresh=isf;
}
void settotal(){
total=scoreMath+scorePolitic+scoreMajor+scoreEnglish;
}
string getname(){
return s_name;
}
string getid(){
return s_id;
}
string getmajor(){
return s_major;
}
string getisf(){
return isfresh;
}
int getMath(){return scoreMath;
}
int getEnglish(){return scoreEnglish;
}
int getMajor(){return scoreMajor;
}
int getPolitic(){return scorePolitic;
}
int getsumscore(){return scoreMath+scoreEnglish+scoreMajor+scorePolitic; }
bool ispassed(const int& po, const int& ma,const int& en, const int& maj,const int& tot);
void setall(const string& na,const string &id,const string& maj,const string& isf,
const int& politic,const int& math,const int& english,const int& major);
friend std::istream& operator>> (std::istream &, student& );
friend std::ostream& operator<< (std::ostream &, student& );
};
#endif // STUDENT_H
student.cpp
#include "student.h"
student::student(const string& na,const string &id,const string& maj,const string& isf,
const int& politic,const int& math,const int& english,const int& major){
setall( na,id,maj, isf, politic,math, english, major);
settotal();
}
void student::setall(const string& na,const string &id,const string& maj,const string& isf,
const int& politic,const int& math,const int& english,const int& major){
setMath(math);
setEnglish(english );
setPolitic(politic);
setMajor(major);
setname( na);
setid( id);
setmajor(maj);
setisf(isf);
}
std::istream& operator >> (std::istream &input, student& s)
{
input >> s.s_name >> s.s_id >> s.s_major >> s.isfresh
>> s.scorePolitic >> s.scoreMath
>> s.scoreEnglish >> s.scoreMajor >>s.total;
return input;
}
std::ostream& operator<< (std::ostream &output, student& s)
{
output << setw(11) << s.s_name;
output << setw(11) << s.s_id;
output << setw(11) << s.s_major;
output << setw(11) << s.isfresh;
output << setw(11) << s.scorePolitic;
output << setw(11) << s.scoreMath;
output << setw(11) << s.scoreEnglish;
output << setw(11) << s.scoreMajor;
output << setw(11) << s.total << "\n";
return output;
}
bool student::ispassed(const int& po, const int& ma,const int& en, const int& maj,const int& tot)
{
if(this->getPolitic() >=po&& //各门课合格
this->getMath() >=ma&&
this->getEnglish() >=en&&
this->getMajor() >=maj&&
this->getsumscore() >=tot)return true;
return false;
}
main.cpp
#include"student.h"
#include
#include
#include
#include
using namespace std;
using std::string;
using std::setw;
class require{
private:
int po;
int ma;
int en;
int maj;
int tot;
public:
require(int p,int m,int e,int n,int t):po(p),ma(m),en(e),maj(n),tot(t){}
require(){
}
int getpo(){
return po;
}
int getma(){
return ma;
}
int geten(){
return en ;
}
int getmaj(){
return maj;
}
int gettot(){
return tot;
}
friend std::istream& operator >> (std::istream &input, require& a)
{
input >> a.po >> a.ma >> a.en >> a.maj
>> a.tot;
return input;
}
};
//************************************
void add(){
ofstream fout("stut.txt",ios::app);
cout<<"***请输入你想增加的人数***"<>n;
student s;
cout<<"---请按顺序输入"<>s;
fout<>id;int k=-1;
student s;
ifstream fin("stut.txt",ios::in);
while(!fin.eof()){
fin>>s;
if(s.getid()==id){
cout<>id;
student *s=new student [20];
student a;
int i=0,k=-1;
ifstream fin("stut.txt",ios::in);
while(!fin.eof()){
fin>>a;
if (fin.fail() )break;
if(id==a.getid()){k=i;
cout<<"原本数据为"<>st;
while(st.getid()!=id) {
cout<<"前后学号不一致,请重新输入!!!!!"<>st;
}
s[k]=st;
ofstream sout("stut.txt",ios::out);
for(int j=0;j>id;
student s[20];
student a;
int i=0;
ifstream fin("stut.txt",ios::in);
while(!fin.eof()){
fin>>a;
if (fin.fail() )break;
if(id==a.getid()){k=i;cout<<"原本数据为"<>stan;
ifstream fin("stut.txt",ios::in);
ofstream out("admission.txt");
while(!fin.eof()){
fin>>s;
if(fin.fail())break;
if(s.ispassed(stan.getpo(),stan.getma(),stan.geten(),stan.getmaj(),stan.gettot())){
out< b.getsumscore() ;
}
void result(){
student *a=new student [20];int i=0;
ifstream infile("admission.txt");
if(!infile){
cout<<"请 先 返 回 菜 单 输 出 过 线 标 准"<>s;
if(infile.fail())break;
a[i++]=s;
}
sort(a,a+i,bmp);
cout<<"以下数据按总分从高到底输出"<>s;
if(fin.fail())break;
if(n==0) cout<>n;
switch(n){
case(1):chaxun();break;
case(2):add();break;
case(3):change();break;
case(4):deletes();break;
case(5):make();result();break;
case(6):shangai();break;
}
cout<<"返回菜单请按1"<>x;
if(x==2) exit(0);
}
}