一、实验内容
实验设计的题目、内容
研究生考试课程为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位操作系统
三、实验课题分析(主要的模块功能、流程图)
3.1需求分析(具体实现要求)
编程统计初试合格的人数,并按总分由高到低的顺序输出合格考生的信息。具体功能:(1)程序运行时首先要求输入:考生姓名,准考证号,报考专业,是否应届生,4门课(政治、数学、外语、专业基础课)成绩。同时,这些原始数据应保存到一个文件中。(2)然后输入:录取的总分要求,各课程的最低分数要求。(3)输出要求:过线考生的姓名,准考证号,报考专业,是否应届生,4门课程(政治、数学、外语、专业基础课)成绩及总分,这些信息应存放到另一个文件中。(4)测试数据。
3.2 研究生初试录取系统的主要功能
3.2.1研究生初试录取系统的主要功能为:
- 查询学生信息 2.增加学生信息
3.修改学生信息 4.删除学生信息
5.输入过线标准并输出合格学生 6.查询删改记录
下图为该系统的功能分解
系统各模块的功能具体描述为:
1、查询操作
输入你想查询的学生的学号(学号唯一并且只能通过学号查找)
系统依次输出该学生的姓名、学号、专业、是否应届生、政治成绩、数学成绩、英语成绩、专业成绩及总分。按“1”返回主菜单,按“2”退出系统。
2、添加操作
可以先输入添加的人数,再输入这些学生的具体信息(界面会给出各个信息的输入顺序,注意一定要按顺序输入),系统把这些数据写入到一个文本中。最后返回菜单。
3、修改操作
可以根据输入的学生学号先查询出该学生的原本信息,再按顺序输入修改后的信息(注意学号唯一且不可修改)系统在把新数据读入到文本中。若在这过程中,学号前后不一致的话,系统自动提醒,并要重新输入。
4、删除学生信息操作
先输入你要删除学生的学号,系统从文本中读到该学号的学生信息,并将其删除,再重新更新文本。同时,将删除的学生信息存到另一个文本中。
5、输入过线标准并且输出过线学生
按科成绩及总分的过线标准,系统从存储学生信息的文件中读取信息,并进行判断,当学号相同时,将该学生的信息存入到另一个文本中,同时排序输出结果。
6、查询删除信息
读取存储删除的学生信息的文本,界面输出结果。
3.3 类的构造
系统涉及对象有两个基本类:学生类和过线要求类。
1)学生类,包含s_name学生姓名、s_id学号、s_major专业、isfresh是否为应届生、scoreMath 数学成绩、scoreEnglish英语成绩、scorePolitic政治成绩、scoreMajor专业课成绩、total总分。
类的声明及定义如下:
#ifndef STUDENT_H
#define STUDENT_H
#include <string>
#include <iostream>
#include <iomanip>
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。
遇到的问题及解决方法如下:
问题1:文件读取失败
5.1.1
问题具体描述:在查询及涉及到读文本的工作时,只能读入第一个数据,所以任何操作都只有第一行有效,查询时只有查第一个才能正常输出,其他系统都提示“该学生找不到”。
5.1.2
问题产生的具体原因:在输出一个学生类的所有信息时,本意是想让只要输入四门课的成绩,总成绩自动计算,不需要手动输入,所以我以前写的类的输入输出函数如下图
但在读写操作时,系统默认这两个类型是不匹配的,因此,读完第一行,系统就会检测不到匹配的类型,便不会继续读下去,这样就导致了这个错误结果。
5.1.3 解决方法
检重新改写类的输入函数,使总分从自动计算,改为手动输入。这样两个类型就匹配了,但是缺点是无法判断总分的正确性,手动输入错误率较高。
图 修改后的输入函数
问题2:文件读取错误
5.2.1问题具体描述
读取文件时最后一行总是会多读一次,输出了两条一模一样的信息,使系统部分功能不能正常运行。
5.2.2 问题产生具体原因
存储的时候,文件最后是换行,仅有eof函数来判断是不行的。
5.2.3问题解决办法
再增加一个条件,最后的时候先判断是否结束,再退出循环
六、实验总结(优点、不足、收获及体会)
我设计的研究生初试录取系统基本满足任务书的功能要求,类的结构和关系清晰,功能完善,能够比较粗略地实现所要求的功能。
存在的主要缺点:第一,没有使用链表,用动态数组来存放临时信息,可能在时间和空间上有一定的消耗;第二个最主要的缺点是,无法判断学生信息是否学号重合、总分是否正确,因为涉及到频繁的读写记录操作。并且我设计的系统把学号当做主键,只能通过学号来查找,这样的代码在实际生活中是及其单薄,甚至是漏洞百出的。
通过这次C++的大型实验,我深刻的明白到:课本知识与实践能力相结合的重要性。上课听得懂不代表真的会打代码了,虽然老师平时给我们的练习题目偏简单,我们也不应该放低对自己的要求,应当脚踏实地,一步步落实,把学到的知识转化为自己的。写代码的过程中,会出现非常非常多的错误,很大一部分原因是平时练习的太少了,实践能力太薄弱了,一写代码便错误百出。编译器只是机械的执行我们所给的指令,纵然代码语法上没有问题了,逻辑硬伤也会使得错误的结果产生,只有理清代码的逻辑关系,耐心编写修改,才能使得系统正常运行。这次的实验课让我熟悉了文件读写等等操作,这些都是我上课并不是很理解的知识,但通过这次实验,我熟悉了这学期学过的操作的使用方法,落实了上课的知识。只有将理论运用到实践中去,你才能深刻地理解这个理论,并在他的基础上举一反三。
(源码可以私我)