908 lines
19 KiB
C++
908 lines
19 KiB
C++
#include "Manager.h"
|
||
#include"Exceptions.h"
|
||
#pragma warning(disable:4996)
|
||
Manager::Manager() {
|
||
centeredPrint("##########################################");
|
||
centeredPrint("## 学生成绩管理系统 ##");
|
||
centeredPrint("##########################################");
|
||
cout << endl;
|
||
centeredPrint("加载中...");
|
||
|
||
ifstream numsin("nums.bin", ios::in, ios::binary);
|
||
if (!numsin.good()) {
|
||
ExamNum = 0;
|
||
StudentNum = 0;
|
||
numsin.close();
|
||
return;
|
||
}
|
||
numsin.read((char*)&StudentNum, sizeof(int));
|
||
numsin.read((char*)&ExamNum, sizeof(int));
|
||
numsin.close();
|
||
ifstream studentsin("students.bin", ios::in, ios::binary);
|
||
Student tmpstu;
|
||
for (int i = 0; i < StudentNum; i++) {
|
||
studentsin.read((char*)&tmpstu, sizeof(Student));
|
||
Students.push_back(tmpstu);
|
||
}
|
||
studentsin.close();
|
||
ifstream examsin("examsaves.bin", ios::in, ios::binary);
|
||
Examsave tmpexam;
|
||
for (int i = 0; i < ExamNum; i++) {
|
||
examsin.read((char*)&tmpexam, sizeof(Examsave));
|
||
auto sp1 = make_shared<Exam>(&tmpexam);
|
||
Exams.push_back(sp1);
|
||
}
|
||
examsin.close();
|
||
|
||
cout << endl;
|
||
centeredPrint("欢迎使用!");
|
||
}
|
||
Manager::~Manager() {
|
||
centeredPrint("保存中...");
|
||
ofstream examsout("examsaves.bin", ios::out, ios::binary);
|
||
for (auto i = Exams.begin(); i < Exams.end(); i++) {
|
||
(*i)->saveAll(examsout);
|
||
}
|
||
ExamNum = Exams.size();
|
||
examsout.close();
|
||
ofstream studentsout("students.bin", ios::out, ios::binary);
|
||
for (auto i = Students.begin(); i < Students.end(); i++) {
|
||
studentsout.write((char*)&(*i), sizeof(Student));
|
||
}
|
||
StudentNum = Students.size();
|
||
studentsout.close();
|
||
ofstream numsout("nums.bin", ios::out, ios::binary);
|
||
numsout.write((char*)&StudentNum, sizeof(int));
|
||
numsout.write((char*)&ExamNum, sizeof(int));
|
||
numsout.close();
|
||
centeredPrint("已保存!");
|
||
}
|
||
void Manager::mainLoop() {
|
||
|
||
while (1) {
|
||
try {
|
||
switch (status) {
|
||
case 0:
|
||
welcomePage();
|
||
break;
|
||
case 1:
|
||
stuPage();
|
||
break;
|
||
case 11:
|
||
stuDspPage();
|
||
break;
|
||
case 12:
|
||
stuAddPage();
|
||
break;
|
||
case 13:
|
||
stuSearchPage();
|
||
break;
|
||
case 14:
|
||
stuEdtRmvPage();
|
||
break;
|
||
case 15:
|
||
stuExportPage();
|
||
break;
|
||
case 16:
|
||
stuImportPage();
|
||
break;
|
||
case 2:
|
||
examPage();
|
||
break;
|
||
case 21:
|
||
examAddPage();
|
||
break;
|
||
case 22:
|
||
examChoosePage();
|
||
break;
|
||
case 23:
|
||
examSubPage();
|
||
break;
|
||
case 231:
|
||
examViewPage();
|
||
break;
|
||
case 232:
|
||
examExportPage();
|
||
break;
|
||
case 233:
|
||
examAddRowPage();
|
||
break;
|
||
case 234:
|
||
examDelRowPage();
|
||
break;
|
||
case 235:
|
||
examNamePage();
|
||
break;
|
||
case 236:
|
||
examImportPage();
|
||
break;
|
||
case 237:
|
||
examRmvPage();
|
||
break;
|
||
case 3:
|
||
stuPfmPage();
|
||
break;
|
||
}
|
||
system("cls");
|
||
if (status == -1)
|
||
break;
|
||
}
|
||
catch (const InputError& e) {
|
||
system("cls");
|
||
cerr << e.what() << endl;
|
||
cin.clear();
|
||
cin.ignore(1024,'\n');
|
||
goBack();
|
||
}
|
||
catch (const FileError& e) {
|
||
system("cls");
|
||
cerr << e.what() << endl;
|
||
goBack();
|
||
}
|
||
catch (const IndexError& e) {
|
||
system("cls");
|
||
cerr << e.what() << endl;
|
||
goBack();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
}
|
||
void Manager::goBack() {
|
||
status /= 10;
|
||
}
|
||
void Manager::centeredPrint(const string& content) {
|
||
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||
CONSOLE_SCREEN_BUFFER_INFO bInfo;
|
||
GetConsoleScreenBufferInfo(hOutput, &bInfo);
|
||
int dwSizeX = bInfo.dwSize.X, dwSizeY = bInfo.dwSize.Y;
|
||
int cursorX = bInfo.dwCursorPosition.X, cursorY = bInfo.dwCursorPosition.Y;
|
||
int len = content.length();
|
||
COORD pos;
|
||
pos.X = (dwSizeX - len) / 2;
|
||
pos.Y = cursorY;
|
||
SetConsoleCursorPosition(hOutput, pos);
|
||
cout << content << endl;
|
||
}
|
||
Student* Manager::searchByNo(long long int studentNo) {
|
||
for (auto i = Students.begin(); i < Students.end(); i++) {
|
||
if (i->stuNoEqual(studentNo)) {
|
||
return &(*i);
|
||
}
|
||
}
|
||
return nullptr;
|
||
}
|
||
//status 0
|
||
void Manager::welcomePage() {
|
||
char choice = '0';
|
||
cout << "主菜单" << endl;
|
||
cout << "请选择" << endl;
|
||
cout << "1: 学生信息管理" << endl;
|
||
cout << "2: 考试信息" << endl;
|
||
cout << "3: 学生成绩查询" << endl;
|
||
cout << "q: 退出" << endl;
|
||
cin >> choice;
|
||
switch (choice) {
|
||
case '1':
|
||
status = 1;
|
||
break;
|
||
case '2':
|
||
status = 2;
|
||
break;
|
||
case '3':
|
||
status = 3;
|
||
break;
|
||
case 'q':
|
||
case 'Q':
|
||
status = -1;
|
||
break;
|
||
}
|
||
}
|
||
//status 1
|
||
void Manager::stuPage() {
|
||
char choice = '0';
|
||
cout << "主菜单-学生" << endl;
|
||
cout << "请选择" << endl;
|
||
cout << "1: 全部学生信息" << endl;
|
||
cout << "2: 添加新学生" << endl;
|
||
cout << "3: 学生信息搜索" << endl;
|
||
cout << "4: 编辑/删除已有学生" << endl;
|
||
cout << "5: 将全部学生信息导出到CSV" << endl;
|
||
cout << "6: 从CSV导入学生信息" << endl;
|
||
cout << "b: 返回" << endl;
|
||
cin >> choice;
|
||
switch (choice) {
|
||
case '1':
|
||
status = 11;
|
||
break;
|
||
case '2':
|
||
status = 12;
|
||
break;
|
||
case '3':
|
||
status = 13;
|
||
break;
|
||
case '4':
|
||
status = 14;
|
||
break;
|
||
case '5':
|
||
status = 15;
|
||
break;
|
||
case '6':
|
||
status = 16;
|
||
break;
|
||
case 'b':
|
||
case 'B':
|
||
goBack();
|
||
}
|
||
}
|
||
//status 11
|
||
void Manager::stuDspPage() {
|
||
cout << "主菜单-学生-信息查看" << endl;
|
||
cout << setw(6) << "编号";
|
||
Student::dspHeader();
|
||
cout << endl;
|
||
int count = 1;
|
||
for (auto student = Students.begin(); student < Students.end(); student++) {
|
||
cout << setw(6) << count++;
|
||
student->dsp();
|
||
cout << endl;
|
||
}
|
||
string tmp;
|
||
cout << endl << "b: 返回" << endl;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|
||
//status 12
|
||
void Manager::stuAddPage() {
|
||
char choice = '0';
|
||
cout << "主菜单-学生-添加" << endl;
|
||
int year;
|
||
int selectionNo;
|
||
int classNo;
|
||
char name[100];
|
||
cout << "姓名:" << endl;
|
||
do {
|
||
cin.getline(name, 100);
|
||
} while (name[0] == '\0');
|
||
cout << "入学年份:" << endl;
|
||
cin >> year;
|
||
cout << "选科组合:" << endl;
|
||
cin >> selectionNo;
|
||
cout << "班级:" << endl;
|
||
cin >> classNo;
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
Students.push_back(Student(year, selectionNo, classNo, name));
|
||
cout << "已添加!" << endl;
|
||
string tmp;
|
||
cout << endl << "b: 返回" << endl;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|
||
//status 13
|
||
void Manager::stuSearchPage() {
|
||
char choice = '0';
|
||
cout << "主菜单-学生-搜索" << endl;
|
||
cout << "请选择:" << endl;
|
||
cout << "1: 按学号搜索" << endl;
|
||
cout << "2: 按姓名搜索" << endl;
|
||
cout << "3: 按班级搜索" << endl;
|
||
cout << "4: 按选科组合搜索" << endl;
|
||
cout << "5: 按入学年份搜索" << endl;
|
||
cout << "b: 返回" << endl;
|
||
cin >> choice;
|
||
vector<Student> result;
|
||
int enrollmentYear;
|
||
switch (choice) {
|
||
case '1':
|
||
long long int inputNo;
|
||
cout << "请输入学号:";
|
||
cin >> inputNo;
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
for (auto stu = Students.begin(); stu < Students.end(); stu++) {
|
||
if (stu->stuNoEqual(inputNo)) {
|
||
result.push_back(*stu);
|
||
}
|
||
}
|
||
break;
|
||
case '2':
|
||
char inputName[100];
|
||
cout << "请输入学生姓名:";
|
||
do {
|
||
cin.getline(inputName, 100);
|
||
} while (inputName[0] == '\0');
|
||
for (auto stu = Students.begin(); stu < Students.end(); stu++) {
|
||
if (stu->nameEqual(inputName)) {
|
||
result.push_back(*stu);
|
||
}
|
||
}
|
||
break;
|
||
case '3':
|
||
int inputClassNo;
|
||
cout << "请输入入学年份:";
|
||
cin >> enrollmentYear;
|
||
cout << "请输入班级:";
|
||
cin >> inputClassNo;
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
for (auto stu = Students.begin(); stu < Students.end(); stu++) {
|
||
if (stu->clsNoEqual(inputClassNo) && stu->yearEqual(enrollmentYear)) {
|
||
result.push_back(*stu);
|
||
}
|
||
}
|
||
break;
|
||
case '4':
|
||
int inputSelectionNo;
|
||
cout << "请输入入学年份:";
|
||
cin >> enrollmentYear;
|
||
cout << "请输入选科组合:";
|
||
cin >> inputSelectionNo;
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
for (auto stu = Students.begin(); stu < Students.end(); stu++) {
|
||
if (stu->slcNoEqual(inputSelectionNo) && stu->yearEqual(enrollmentYear)) {
|
||
result.push_back(*stu);
|
||
}
|
||
}
|
||
break;
|
||
case '5':
|
||
cout << "请输入入学年份:";
|
||
cin >> enrollmentYear;
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
for (auto stu = Students.begin(); stu < Students.end(); stu++) {
|
||
if (stu->yearEqual(enrollmentYear)) {
|
||
result.push_back(*stu);
|
||
}
|
||
}
|
||
break;
|
||
case 'b':
|
||
case 'B':
|
||
goBack();
|
||
}
|
||
if (status != 1) {
|
||
cout << setw(6) << "编号";
|
||
Student::dspHeader();
|
||
cout << endl;
|
||
int count = 1;
|
||
for (auto student = result.begin(); student < result.end(); student++) {
|
||
cout << setw(6) << count++;
|
||
student->dsp();
|
||
cout << endl;
|
||
}
|
||
cout << endl;
|
||
if (result.size() == 0) {
|
||
cout << "未找到符合条件的学生" << endl;
|
||
}
|
||
cout << "b: 返回" << endl;
|
||
string tmp;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|
||
}
|
||
//status 14
|
||
void Manager::stuEdtRmvPage() {
|
||
int inputNo;
|
||
string tmp;
|
||
cout << "主菜单-学生-编辑/删除" << endl;
|
||
cout << "请输入学号:";
|
||
cin >> inputNo;
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
auto it = Students.end();
|
||
for (auto stu = Students.begin(); stu < Students.end(); stu++) {
|
||
if (stu->stuNoEqual(inputNo)) {
|
||
it = stu;
|
||
}
|
||
}
|
||
if (it == Students.end()) {
|
||
cout << "查无此人" << endl;
|
||
cout << "b: 返回" << endl;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|
||
else {
|
||
char choice;
|
||
cout << "1: 编辑学生信息" << endl;
|
||
cout << "2: 删除" << endl;
|
||
cin >> choice;
|
||
Student::dspHeader();
|
||
cout << endl;
|
||
it->dsp();
|
||
cout << endl;
|
||
if (choice == '1') {
|
||
|
||
int year;
|
||
int selectionNo;
|
||
int classNo;
|
||
char name[100];
|
||
cout << "姓名:" << endl;
|
||
do {
|
||
cin.getline(name, 100);
|
||
} while (name[0] == '\0');
|
||
cout << "入学年份:" << endl;
|
||
cin >> year;
|
||
cout << "选科组合:" << endl;
|
||
cin >> selectionNo;
|
||
cout << "班级:" << endl;
|
||
cin >> classNo;
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
it->setInfo(year, selectionNo, classNo, name);
|
||
cout << "已修改" << endl;
|
||
}
|
||
else if (choice == '2') {
|
||
cout << "删除上述学生?(Y(是)/N(否))" << endl;
|
||
char yorn;
|
||
cin >> yorn;
|
||
if (yorn == 'y' || yorn == 'Y') {
|
||
Students.erase(it);
|
||
}
|
||
cout << "已删除" << endl;
|
||
}
|
||
cout << "b: 返回" << endl;
|
||
string tmp;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|
||
}
|
||
//status 15
|
||
void::Manager::stuExportPage() {
|
||
cout << "主菜单-学生-导出" << endl;
|
||
string csvName;
|
||
cout << "请输入导出文件名:" << endl;
|
||
do {
|
||
getline(cin, csvName);
|
||
} while (csvName == "");
|
||
csvName = csvName + ".csv";
|
||
ofstream csv(csvName);
|
||
if (!csv.good()) {
|
||
throw FileError("文件创建失败!");
|
||
}
|
||
Student::toCsvHeader(csv);
|
||
csv << '\n';
|
||
for (auto student = Students.begin(); student < Students.end(); student++) {
|
||
student->toCsv(csv);
|
||
csv << '\n';
|
||
}
|
||
string tmp;
|
||
cout << "导出成功" << endl;
|
||
cout << "b: 返回" << endl;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|
||
//status 16
|
||
void::Manager::stuImportPage() {
|
||
string fileName;
|
||
string tmp;
|
||
bool eof = false;
|
||
int firstRow=1;
|
||
int clsColumn, slcColumn, yearColumn,nameColumn;
|
||
cout << "主菜单-学生-导入" << endl;
|
||
cout << "请输入文件名称或路径,注意包含扩展名" << endl;
|
||
cin >> fileName;
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
ifstream csvFile(fileName);
|
||
if (!csvFile.good()) {
|
||
throw FileError("文件打开失败!");
|
||
}
|
||
cout << "请输入有效数据开始的行数: " << endl;
|
||
cin >> firstRow;
|
||
cout << "请输入学生姓名所在的列数: " << endl;
|
||
cin >> nameColumn;
|
||
cout << "请输入入学年份所在的列数: " << endl;
|
||
cin >> yearColumn;
|
||
cout << "请输入班号所在的列数: " << endl;
|
||
cin >> clsColumn;
|
||
cout << "请输入选科组合所在的列数: " << endl;
|
||
cin >> slcColumn;
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
for (int i = 1; i < firstRow; i++) {
|
||
getline(csvFile, tmp);
|
||
}
|
||
while (!eof) {
|
||
Student tmpStu(csvFile, yearColumn, clsColumn, slcColumn, nameColumn);
|
||
if (tmpStu.stuNoEqual(-1)) {
|
||
eof = true;
|
||
|
||
}
|
||
else if (tmpStu.stuNoEqual(0)) {
|
||
continue;
|
||
}
|
||
else {
|
||
Students.push_back(tmpStu);
|
||
}
|
||
}
|
||
|
||
cout << "已导入" << endl;
|
||
cout << "b: 返回" << endl;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|
||
//status 2
|
||
void Manager::examPage() {
|
||
char choice = '0';
|
||
cout << "主菜单-考试" << endl;
|
||
cout << setw(6) << "编号";
|
||
Exam::dspHeader();
|
||
for (auto exam = Exams.begin(); exam < Exams.end(); exam++) {
|
||
cout << setw(4) << distance(Exams.begin(), exam) + 1;
|
||
(*exam)->dsp();
|
||
}
|
||
cout << endl;
|
||
cout << "请选择" << endl;
|
||
cout << "1: 添加考试" << endl;
|
||
cout << "2: 选择考试" << endl;
|
||
cout << "b: 返回" << endl;
|
||
cin >> choice;
|
||
switch (choice) {
|
||
case '1':
|
||
status = 21;
|
||
break;
|
||
case '2':
|
||
status = 22;
|
||
break;
|
||
case 'b':
|
||
case 'B':
|
||
goBack();
|
||
break;
|
||
}
|
||
}
|
||
//status 21
|
||
void Manager::examAddPage() {
|
||
cout << "主菜单-考试-添加" << endl;
|
||
cout << "名称:" << endl;
|
||
char name[100];
|
||
do {
|
||
cin.getline(name, 100);
|
||
} while (name[0] == '\0');
|
||
auto p = make_shared<Exam>(name);
|
||
Exams.push_back(p);
|
||
cout << "添加成功!" << endl;
|
||
cout << "b: 返回" << endl;
|
||
string tmp;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|
||
//status 22
|
||
void Manager::examChoosePage() {
|
||
int examNo;
|
||
string tmp;
|
||
cout << "主菜单-考试-选择" << endl;
|
||
cout << setw(6) << "编号";
|
||
Exam::dspHeader();
|
||
for (auto exam = Exams.begin(); exam < Exams.end(); exam++) {
|
||
cout << setw(6) << distance(Exams.begin(), exam) + 1;
|
||
(*exam)->dsp();
|
||
}
|
||
cout << endl;
|
||
cout << "编号:" << endl;
|
||
cin >> examNo;
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
examNo--;
|
||
if (examNo >= 0 && examNo < Exams.size()) {
|
||
currentExam = Exams.begin() + examNo;
|
||
|
||
status = 23;
|
||
}
|
||
else {
|
||
throw IndexError("编号无效!");
|
||
}
|
||
}
|
||
//status 23
|
||
void Manager::examSubPage() {
|
||
cout << "主菜单-考试-";
|
||
(*currentExam)->dspName();
|
||
cout << endl;
|
||
|
||
cout << "请选择:" << endl;
|
||
cout << "1: 查看全部成绩" << endl;
|
||
cout << "2: 导出为CSV" << endl;
|
||
cout << "3: 新增成绩" << endl;
|
||
cout << "4: 删除成绩" << endl;
|
||
cout << "5: 修改考试名称" << endl;
|
||
cout << "6: 从CSV导入" << endl;
|
||
cout << "7: 删除此考试及其所有成绩信息" << endl;
|
||
cout << "b: 返回" << endl;
|
||
char choice = '0';
|
||
cin >> choice;
|
||
switch (choice) {
|
||
case '1':
|
||
status = 231;
|
||
break;
|
||
case '2':
|
||
status = 232;
|
||
break;
|
||
case '3':
|
||
status = 233;
|
||
break;
|
||
case '4':
|
||
status = 234;
|
||
break;
|
||
case '5':
|
||
status = 235;
|
||
break;
|
||
case '6':
|
||
status = 236;
|
||
break;
|
||
case '7':
|
||
status = 237;
|
||
break;
|
||
case 'b':
|
||
case 'B':
|
||
goBack();
|
||
}
|
||
}
|
||
//status 231
|
||
void Manager::examViewPage() {
|
||
|
||
cout << "主菜单-考试-";
|
||
(*currentExam)->dspName();
|
||
cout << "-查看" << endl;
|
||
Item::dspHeader();
|
||
cout <<setw(6)<< "名次" << endl;
|
||
(*currentExam)->dspItems();
|
||
string tmp;
|
||
cout << endl << "b: 返回" << endl;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|
||
//status 232
|
||
void Manager::examExportPage() {
|
||
|
||
string csvName;
|
||
|
||
cout << "主菜单-考试-";
|
||
(*currentExam)->dspName();
|
||
cout << "-导出" << endl;
|
||
cout << "请输入导出文件名:" << endl;
|
||
do {
|
||
getline(cin, csvName);
|
||
} while (csvName == "");
|
||
csvName = csvName + ".csv";
|
||
ofstream csv(csvName);
|
||
if (!csv.good()) {
|
||
throw FileError("文件创建失败!");
|
||
}
|
||
Item::toCsvHeader(csv);
|
||
csv << "名次" << endl;
|
||
(*currentExam)->toCsvItems(csv);
|
||
csv.close();
|
||
cout << "导出完成" << endl;
|
||
string tmp;
|
||
cout << endl << "b: 返回" << endl;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|
||
//status 233
|
||
void Manager::examAddRowPage() {
|
||
long long int studentNo;
|
||
double score[9];
|
||
char yorn;
|
||
|
||
cout << "主菜单-考试-";
|
||
(*currentExam)->dspName();
|
||
cout << "-新增成绩" << endl;
|
||
|
||
cout << "学号:" << endl;
|
||
cin >> studentNo;
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
if ((*currentExam)->itemExists(studentNo)) {
|
||
cout << "学号" << studentNo << "的成绩已存在, 是否覆盖? (Y(是)/N(否))" << endl;
|
||
cin >> yorn;
|
||
if (yorn != 'Y' && yorn != 'y') {
|
||
status = 23;
|
||
return;
|
||
}
|
||
}
|
||
cout << "数学:" << endl;
|
||
cin >> score[0];
|
||
cout << "语文:" << endl;
|
||
cin >> score[1];
|
||
cout << "英语:" << endl;
|
||
cin >> score[2];
|
||
cout << "物理:" << endl;
|
||
cin >> score[3];
|
||
cout << "化学:" << endl;
|
||
cin >> score[4];
|
||
cout << "生物:" << endl;
|
||
cin >> score[5];
|
||
cout << "历史:" << endl;
|
||
cin >> score[6];
|
||
cout << "政治:" << endl;
|
||
cin >> score[7];
|
||
cout << "地理:" << endl;
|
||
cin >> score[8];
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
(*currentExam)->addItem(studentNo, score);
|
||
cout << "已添加" << endl;
|
||
string tmp;
|
||
cout << endl << "b: 返回" << endl;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|
||
//status 234
|
||
void Manager::examDelRowPage() {
|
||
char yorn;
|
||
long long int studentNo;
|
||
string tmp;
|
||
|
||
cout << "主菜单-考试-";
|
||
(*currentExam)->dspName();
|
||
cout << "-删除成绩" << endl;
|
||
|
||
cout << "学号:" << endl;
|
||
cin >> studentNo;
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
cout << "确认删除(Y(是)/N(否))" << endl;
|
||
cin >> yorn;
|
||
if (yorn == 'Y' || yorn == 'y') {
|
||
yorn=(*currentExam)->rmvItem(studentNo);
|
||
if (yorn) {
|
||
cout << "已删除" << endl;
|
||
}
|
||
else {
|
||
cout << "未找到" << endl;
|
||
}
|
||
}
|
||
else {
|
||
cout << "已取消" << endl;
|
||
}
|
||
cout << "b: 返回" << endl;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|
||
//status 235
|
||
void Manager::examNamePage() {
|
||
string tmp;
|
||
char name[100];
|
||
cout << "主菜单-考试-";
|
||
(*currentExam)->dspName();
|
||
cout << "-修改名称" << endl;
|
||
cout << "新名称:" << endl;
|
||
do {
|
||
cin.getline(name, 100);
|
||
} while (name[0] == '\0');
|
||
(*currentExam)->changeName(name);
|
||
cout << "已修改" << endl;
|
||
cout << "b: 返回" << endl;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|
||
//status 236
|
||
void Manager::examImportPage() {
|
||
string tmp;
|
||
string fileName;
|
||
int firstRow;
|
||
int stuNoColumn;
|
||
int scoreColumn[9];
|
||
bool eof=false;
|
||
char name[100];
|
||
cout << "主菜单-考试-";
|
||
(*currentExam)->dspName();
|
||
cout << "-导入" << endl;
|
||
cout << "注意,若此考试中已存在相同学号学生的成绩数据,从CSV导入的数据会将其覆盖" << endl;
|
||
cout << "请输入文件名称或路径,注意包含扩展名" << endl;
|
||
cin >> fileName;
|
||
ifstream csvFile(fileName);
|
||
if (!csvFile.good()) {
|
||
throw FileError("文件打开失败!");
|
||
}
|
||
cout << "请输入有效数据开始的行数: " << endl;
|
||
cin >> firstRow;
|
||
cout << "请输入学号所在的列数:" << endl;
|
||
cin >> stuNoColumn;
|
||
cout << "请输入数学、语文、英语、物理、化学、生物、历史、政治、地理成绩所在的列数,以空格分隔" << endl;
|
||
cin >> scoreColumn[0] >> scoreColumn[1] >> scoreColumn[2] >> scoreColumn[3] >> scoreColumn[4] >> scoreColumn[5] >> scoreColumn[6] >> scoreColumn[7] >> scoreColumn[8];
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
for (int i = 1; i < firstRow; i++) {
|
||
getline(csvFile, tmp);
|
||
}
|
||
while (!eof) {
|
||
Item tmpItem(csvFile, stuNoColumn, scoreColumn);
|
||
if (tmpItem.getStuNo()==-1) {
|
||
eof = true;
|
||
}
|
||
else if(tmpItem.getStuNo()==0) {
|
||
continue;
|
||
}
|
||
else {
|
||
(*currentExam)->addItem(tmpItem);
|
||
}
|
||
}
|
||
|
||
cout << "已导入" << endl;
|
||
cout << "b: 返回" << endl;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|
||
//status 237
|
||
void Manager::examRmvPage() {
|
||
string tmp;
|
||
|
||
cout << "主菜单-考试-";
|
||
(*currentExam)->dspName();
|
||
cout << "-删除考试" << endl;
|
||
cout << "你确定要删除考试\"";
|
||
(*currentExam)->dspName();
|
||
cout<< "\"吗" << endl;
|
||
cout << "输入 \"confirm\" 以确认删除" << endl;
|
||
cin >> tmp;
|
||
if (tmp == "confirm") {
|
||
(*currentExam)->rm();
|
||
Exams.erase(currentExam);
|
||
currentExam = Exams.begin();
|
||
goBack();
|
||
goBack();
|
||
cout << "已删除" << endl;
|
||
}
|
||
else {
|
||
goBack();
|
||
cout << "已取消" << endl;
|
||
}
|
||
cout << "b: 返回" << endl;
|
||
cin >> tmp;
|
||
|
||
}
|
||
//status 3
|
||
void Manager::stuPfmPage() {
|
||
long long int studentNo;
|
||
cout << "主菜单-学生成绩查询" << endl;
|
||
cout << "学号:" << endl;
|
||
cin >> studentNo;
|
||
if (!cin.good()) {
|
||
throw InputError("输入字符非法!");
|
||
}
|
||
Student::dspHeader();
|
||
cout << endl;
|
||
if (searchByNo(studentNo) == nullptr) {
|
||
cout << setw(20) << "未找到数据" << endl;
|
||
}
|
||
else {
|
||
searchByNo(studentNo)->dsp();
|
||
}
|
||
cout << endl << endl;
|
||
cout << "历次考试成绩:" << endl<<endl;
|
||
cout << setw(20) << "考试名称";
|
||
Item::dspHeader(0);
|
||
cout << setw(6) << "名次" << endl;
|
||
for (auto exam = Exams.begin(); exam < Exams.end(); exam++) {
|
||
auto item = (*exam)->StudentInquiry(studentNo);
|
||
(*exam)->dspName(20);
|
||
if (item == nullptr) {
|
||
cout << setw(20) << "未找到数据" << endl;
|
||
}
|
||
else {
|
||
item->dsp(0);
|
||
cout << setw(6)<<(*exam)->getStuRanking(*item)<<endl;
|
||
}
|
||
}
|
||
string tmp;
|
||
cout <<endl<< "b: 返回" << endl;
|
||
cin >> tmp;
|
||
goBack();
|
||
}
|