建立一个菜单,进行选择功能操作。功能选择如下:
1、实现学生成绩录入,并将录入数据保存到文本文件中;
2、读取文件中的学生成绩,并进行显示;
3、查询某个学号学生的所有成绩;
4、查询某课程编号的所有学生的成绩;
5、某课程编号的所有学生的成绩的排序显示;
6、统计各学生的学分;
7、统计学分绩点小于某个值的所有学生;
8、修改某个学生的指定成绩小于某个值的所有学生;
9、统计某个学号学生的某个学期的平均成绩。
//学生成绩类的头文件:
//xscj.h
#pragma once //保证头文件只被编译一次
#include <iostream>
#include <string>
using namespace std;
class xscj
{
public:
xscj() :xh(0), kcbh(0), kcmc(""), pscj(0), qmcj(0), zpcj(0), xf(0), kcjd(0), kkxq(0) {};
xscj(int xh1, int kcbh1, string kcmc1, float pscj1, float qmcj1, float xf1, int kkxq1);
int getxh() { return xh; }
int getkcbh() { return kcbh; }
string getkcmc() { return kcmc; }
float getpscj() { return pscj; }
float getqmcj() { return qmcj; }
float getzpcj() { return zpcj; }
float getxf() { return xf; }
float getkcjd() { return kcjd; }
int getkkxq() { return kkxq; }
void show();
void setxh(int xh1) { xh = xh1; }
void setkcbh(int kcbh1) { kcbh = kcbh1; }
void setkcmc(string kcmc1) { kcmc = kcmc1; }
void setxf(float xf1) { xf = xf1; }
void setpscj(float pscj1);
void setqmcj(float qmcj1);
void setkkxq(int kkxq1) { kkxq = kkxq1; }
private:
int xh; //学号
int kcbh; //课程编号
string kcmc; //课程名称
float pscj; //平时成绩
float qmcj; //期末成绩
float zpcj; //总评成绩
float xf; //学分
float kcjd; //课程绩点
int kkxq; //开课学期
};
//学生成绩类的源文件:
//xscj.cpp
#include "xscj.h"
#include <iostream>
#include <iomanip> //IO流控制头文件
using namespace std;
//带参数的构造函数
xscj::xscj(int xh1, int kcbh1, string kcmc1, float pscj1, float qmcj1, float xf1, int kkxq1)
{
xh = xh1;
kcbh = kcbh1;
kcmc = kcmc1;
pscj = pscj1;
qmcj = qmcj1;
zpcj = (pscj + qmcj) / 2;
kcjd = (static_cast<int>(zpcj / 10)) * xf / 10;
xf = xf1;
kkxq = kkxq1;
}
void xscj::show()
{
// setw(10) 输出数据时宽度为10 不足10的话左端补空格
// setprecision(5) 不计入小数点
cout << xh << '\t' << setw(10) << kcbh << '\t' << setw(25) << kcmc << '\t' << xf << '\t' << setprecision(5)
<< pscj << '\t' << setprecision(5) << qmcj << '\t' << setprecision(5) << zpcj << '\t' << setprecision(5)
<< kcjd << '\t' << kkxq << endl;
}
//对平时成绩、期末成绩的修改同时涉及到总评成绩和课程绩点
//总评成绩 = 期末成绩 / 2 + 平时成绩 /2
//课程绩点 = (总评成绩 / 10 ) * (学分 / 10)
void xscj::setpscj(float pscj1) {
pscj = pscj1;
zpcj = (pscj + qmcj) / 2;
kcjd = (static_cast<int>(zpcj / 10)) * xf / 10;
}
void xscj::setqmcj(float qmcj1) {
qmcj = qmcj1;
zpcj = (pscj + qmcj) / 2;
kcjd = (static_cast<int>(zpcj / 10)) * xf / 10;
}
//学生成绩管理系统头文件:
//xscjop.h
#pragma once
#include "xscj.h"
#include <vector>
#include <fstream>
using namespace std;
class xscjop
{
public:
void xscjlr(); //成绩录入
void addTofile(xscj cj); //增加单个学生成绩到文件 以追加方式
void saveTofile(); //把修改后的成绩保存到文件 以覆盖方式(实时更新数据)
void readFromfile(); //从文件中读取成绩并存入数组
void xscjshow(); //显示所有学生成绩
void select_student_all(); //查询某个学生的所有成绩
void select_course_all(); //查询某个课程编号所有学生的成绩
void select_course_all_sort(); //某个课程编号所有学生的成绩(排序显示)
void sum_student_xf(); //统计各学生的学分
void select_xfjd(); //查询绩点小于某个值的所有学生
void uptate_student_kccj(); //修改某个学生指定课程成绩
void xueqi_avg(); //统计学生学期平均成绩
void kkxq_ok(int& kkxq1); //开课学期合法性判断
void cj_ok(float& cj); //成绩合法性判断
void xh_ok(int& xh); //学号存在判断
void kcbh_ok(int& kcbh);
private:
vector<xscj>xscjArr;
};
//学生成绩管理系统源文件:
//xscjop.cpp
#include "xscjop.h"
void xscjop::xscjlr()
{
char flag = 1;
xscj cj;
int itemp;
float ftemp;
string kcmc;
while (flag)
{
cout << "请输入学号:" << endl;
cin >> itemp;
cj.setxh(itemp);
cout << "请输入课程编号:" << endl;
cin >> itemp;
cj.setkcbh(itemp);
cout << "请输入课程名称:" << endl;
cin >> kcmc;
cj.setkcmc(kcmc);
cout << "请输入课程学分:" << endl;
cin >> ftemp;
cj.setxf(ftemp);
cout << "请输入平时成绩:" << endl;
cin >> ftemp;
cj_ok(ftemp); //判断成绩合法性
cj.setpscj(ftemp);
cout << "请输入期末成绩:" << endl;
cin >> ftemp;
cj_ok(ftemp);
cj.setqmcj(ftemp);
cout << "请输入开课学期(1 or 2):" << endl;
cin >> itemp;
kkxq_ok(itemp); //判断开课学期合法性
cj.setkkxq(itemp);
cj.show();
//将录入的文件保存到容器
xscjArr.push_back(cj);
//将录入的数据写入文件 每录一次写一次
addTofile(cj);
cout << "是否继续输入?(输入 Y / N):";
cin >> flag;
if (flag != 'y' && flag != 'Y')
break;
}
system("pause");
system("cls");
}
void xscjop::addTofile(xscj cj)
{
fstream cjouttxt;
cjouttxt.open("xscj.txt", ios::app | ios::out);
//追加单条数据
cjouttxt << cj.getxh() << " " << cj.getkcbh() << " " << cj.getkcmc() << " "
<< cj.getxf() << " " << cj.getpscj() << " " << cj.getqmcj() << " "
<< cj.getzpcj() << " "<< cj.getkcjd() << " " << cj.getkkxq() << endl;
cjouttxt.close();
}
void xscjop::saveTofile()
{
fstream cjouttxt;
cjouttxt.open("xscj.txt", ios::out);
//把容器中所有数据写入文件 并覆盖之前的数据
for (auto a : xscjArr)
{
cjouttxt << a.getxh() << " " << a.getkcbh() << " " << a.getkcmc() << " "<< a.getxf() << " " << a.getpscj() << " " << a.getqmcj() << " "
<<a.getzpcj() << " "<< a.getkcjd() << " " << a.getkkxq() << endl;
}
cjouttxt.close();
}
void xscjop::readFromfile()
{
fstream cjin;
cjin.open("xscj.txt", ios::in);
//把原先容器中的内容清除掉 避免重复写入
xscjArr.clear();
//用于容器添加数据
xscj cj;
//用来接收文件中数据的变量
int xh, kcbh, kkxq;
string kcmc;
float xf, pscj, qmcj, zpcj, kcjd;
//文件打开成功
if (cjin)
{
//cout << "读取中..." << endl;
//读取到最后一个标识符退出循环
while (!cjin.eof())
{
//依次将文件中的数据保存到cj中
cjin >> xh;
cjin >> kcbh;
cjin >> kcmc;
cjin >> xf;
cjin >> pscj;
cjin >> qmcj;
cjin >> zpcj;
cjin >> kcjd;
cjin >> kkxq;
cj.setxh(xh);
cj.setkcbh(kcbh);
cj.setkcmc(kcmc);
cj.setxf(xf);
cj.setpscj(pscj);
cj.setqmcj(qmcj);
cj.setkkxq(kkxq);
//将cj添加至容器
xscjArr.push_back(cj);
//解决文件重复读取最后一行的问题 eof()返回的是最后一个字符的下一个字符
cjin.get(); //读取每一行之后的下一个字符
if (cjin.peek() == '\n') //peek()返回值是指针指向的当前字符 如果当前字符为换行符 则说明已经到文件最后了
break;
//测试文件读取是否正常
//cj.show();
}
cjin.close();
}
else
cout << "文件打开失败!" << endl;
}
void xscjop::xscjshow()
{
for (auto a : xscjArr)
{
a.show();
}
system("pause");
system("cls");
}
void xscjop::select_student_all()
{
//先把文件中的数据读到容器
readFromfile();
int xh;
cout << "请输入要查询的学生学号: ";
cin >> xh;
xh_ok(xh);
for (auto a : xscjArr)
{
if (a.getxh() == xh)
{
a.show();
}
}
system("pause");
system("cls");
}
void xscjop::select_course_all()
{
readFromfile();
int kcbh;
cout << "请输入要查询的课程编号: ";
cin >> kcbh;
kcbh_ok(kcbh);
for (auto a : xscjArr)
{
if (a.getkcbh() == kcbh)
{
a.show();
}
}
system("pause");
system("cls");
}
void xscjop::select_course_all_sort()
{
readFromfile();
vector<xscj>kcsort; //存储需要排序的课程
xscj temp;
int type;
int kcbh;
int length = xscjArr.size(); //学生成绩长度
cout << "请输入要查询的课程编号: ";
cin >> kcbh;
kcbh_ok(kcbh);
//将需要排序的课程的装入到kcsort
for (int i = 0; i < length; i++)
{
if (xscjArr[i].getkcbh() == kcbh)
{
temp = xscjArr[i];
kcsort.push_back(temp);
}
}
int length_s = kcsort.size(); //需要排序的数组长度
//选择排序 降序
for (int i = 0; i <= length_s; i++)
{
for (int j = i + 1; j <= length_s - 1; j++)
if (kcsort[i].getzpcj() > kcsort[j].getzpcj())
{
temp = kcsort[i];
kcsort[i] = kcsort[j];
kcsort[j] = temp;
}
}
//显示排序后成绩
cout << "请输入 1 or 2 (1、降序 2、升序) :";
while (1) {
cin >> type;
switch (type)
{
case 1:
for (auto a : kcsort)
a.show();
system("pause");
system("cls");
return;
break;
case 2:
for (int i = length_s - 1; i >= 0; i--) //降序
kcsort[i].show();
system("pause");
system("cls");
return;
break;
default:
cout << "输入的排序类型不正确,请重新输入:";
break;
}
}
}
void xscjop::sum_student_xf()
{
readFromfile();
int xh;
float xf_sum = 0;
cout << "请输入要查询的学生学号: ";
cin >> xh;
xh_ok(xh);
for (auto a : xscjArr)
{
if (a.getxh() == xh)
{
a.show();
xf_sum += a.getxf();
}
}
cout << "学号" << xh << "的学生总学分为:" << xf_sum << endl;
system("pause");
system("cls");
}
void xscjop::select_xfjd()
{
readFromfile();
int jd;
int flag = 1;
cout << "请输入要筛选的绩点值(显示低于此绩点值的学生) :";
cin >> jd;
for (auto a : xscjArr)
{
if (a.getkcjd() < jd)
{
a.show();
flag = 0;
}
}
if (flag)
{
cout << "无低于此绩点的学生!" << endl;
}
system("pause");
system("cls");
}
void xscjop::uptate_student_kccj()
{
readFromfile();
int xh, kcbh,kkxq;
float pscj, qmcj;
cout << "请输入学生学号:";
cin >> xh;
xh_ok(xh);
cout << "请输入要修改的课程编号:";
cin >> kcbh;
kcbh_ok(kcbh);
//for(auto &a:b)中加了引用符号,可以对容器中的内容进行赋值,即可通过对a赋值来做到容器b的内容填充。
for (auto &&a : xscjArr)
{
if (a.getxh() == xh && a.getkcbh() == kcbh)
{
a.show();
cout << "请输入新平时成绩:";
cin >> pscj;
cj_ok(pscj);
a.setpscj(pscj);
cout << "请输入新期末成绩:";
cin >> qmcj;
cj_ok(qmcj);
a.setqmcj(qmcj);
a.show();
}
}
//修改完成后更新文本文件中的内容
saveTofile();
system("pause");
system("cls");
}
void xscjop::xueqi_avg()
{
readFromfile();
int xh, kkxq;
int count = 0; //选课门数
float sum = 0;
cout << "请输入要查询的学生学号: ";
cin >> xh;
xh_ok(xh);
cout << "请输入要查询的开课学期(1 or 2): ";
cin >> kkxq;
kkxq_ok(kkxq);
for (auto a : xscjArr)
{
if (a.getxh() == xh && a.getkkxq() == kkxq)
{
count++;
sum += a.getzpcj();
a.show();
}
}
cout << "学号" << xh << "的学生第" << kkxq << "学期的平均成绩为:" << sum / count << endl;
system("pause");
system("cls");
}
//开课学期合法性判断
void xscjop::kkxq_ok(int& kkxq1)
{
if (kkxq1 != 1 && kkxq1 != 2)
{
while (1) {
cout << "输入的开课学期不合法!请重新输入:";
cin >> kkxq1;
if (kkxq1 == 1 || kkxq1 == 2)
return;
}
}
}
void xscjop::cj_ok(float& cj) {
if (cj < 0 || cj > 100)
{
while (1) {
cout << "输入的成绩不合法!请重新输入(0~100):";
cin >> cj;
if (cj >= 0 && cj <= 100)
return;
}
}
}
void xscjop::xh_ok(int& xh)
{
int flag = 1;
for (auto a : xscjArr)
{
if (a.getxh() == xh)
{
flag = 0;
}
}
//如果学号不存在
while (flag)
{
cout << "学号输入有误,请重新输入:";
cin >> xh;
for (auto a : xscjArr)
{
if (a.getxh() == xh)
{
flag = 0;
}
}
}
}
void xscjop::kcbh_ok(int& kcbh)
{
int flag = 1;
for (auto a : xscjArr)
{
if (a.getkcbh() == kcbh)
{
flag = 0;
}
}
//如果课程编号不存在
while (flag)
{
cout << "课程编号输入有误,请重新输入:";
cin >> kcbh;
for (auto a : xscjArr)
{
if (a.getkcbh() == kcbh)
{
flag = 0;
}
}
}
}
//主函数代码:
#include "xscj.h"
#include "xscjop.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <stdlib.h>
using namespace std;
//菜单显示声明
void menu_show();
int main() {
int i;
xscjop x;
while (1) {
menu_show();
cout << "请输入菜单选项 : ";
cin >> i;
switch (i)
{
case 1:
x.xscjlr();
break;
case 2:
x.readFromfile();
x.xscjshow();
break;
case 3:
x.select_student_all();
break;
case 4:
x.select_course_all();
break;
case 5:
x.select_course_all_sort();
break;
case 6:
x.sum_student_xf();
break;
case 7:
x.select_xfjd();
break;
case 8:
x.uptate_student_kccj();
break;
case 9:
x.xueqi_avg();
break;
case 0:
cout << "退出学生成绩系统!" << endl;
system("pause");
return 0;
break;
default:
cout << "输入错误,请重新输入!" << endl;
break;
}
}
return 0;
}
void menu_show()
{
cout << endl;
cout << "\t\t\t" << "************************功能菜单******************************" << endl;
cout << "\t\t\t" << "* *" << endl;
cout << "\t\t\t" << "* 1.录入学生成绩 *" << endl;
cout << "\t\t\t" << "* 2.读取学生成绩 *" << endl;
cout << "\t\t\t" << "* 3.查询学生成绩 *" << endl;
cout << "\t\t\t" << "* 4.查询课程成绩 *" << endl;
cout << "\t\t\t" << "* 5.查询课程成绩 (排序显示) *" << endl;
cout << "\t\t\t" << "* 6.统计学生学分 *" << endl;
cout << "\t\t\t" << "* 7.查询学分绩点低于某个值的所有学生 *" << endl;
cout << "\t\t\t" << "* 8.修改学生课程成绩 *" << endl;
cout << "\t\t\t" << "* 9.查询学生学期平均成绩 *" << endl;
cout << "\t\t\t" << "* 0.退出学生成绩系统 *" << endl;
cout << "\t\t\t" << "* *" << endl;
cout << "\t\t\t" << "**************************************************************" << endl << endl;
}