hello world

This commit is contained in:
smh 2023-09-02 15:36:45 +08:00
commit 52dd9b6adf
9 changed files with 1477 additions and 0 deletions

134
Exam.cpp Normal file
View File

@ -0,0 +1,134 @@
#pragma warning(disable:4996)
#include"Exam.h"
using namespace std;
Exam::Exam(Examsave* insave) {
this->save = *insave;
studentnum = insave->studentnum;
strcpy(name, insave->name);
strcpy(filename, insave->filename);
ifstream ibin(filename, ios::in, ios::binary);
Item tmp;
for (int i = 0; i < studentnum; i++) {
ibin.read((char*)&tmp, sizeof(Item));
items.push_back(tmp);
}
ibin.close();
if (items.size() > 0) {
sort(items.begin(), items.end());
reverse(items.begin(), items.end());
}
}
Exam::Exam(char inname[]) {
strcpy(name, inname);
studentnum = 0;
ifstream tmp(inname, ios::in, ios::binary);
if (tmp.good()) {
string nname;
nname += inname;
for (auto i = 1; i < 100; i++) {
nname += to_string(i);
ifstream tmp(nname, ios::in, ios::binary);
if (!tmp.good()) {
break;
}
}
strcpy(filename, nname.c_str());
}
else {
strcpy(filename, inname);
}
}
void Exam::addItem(long long int studentNo, double score[9]) {
rmvItem(studentNo);
Item tmp(studentNo, score);
items.push_back(tmp);
sort(items.begin(), items.end());
reverse(items.begin(), items.end());
studentnum++;
}
void Exam::addItem(const Item& item) {
rmvItem(item.getStuNo());
items.push_back(item);
sort(items.begin(), items.end());
reverse(items.begin(), items.end());
studentnum++;
}
void Exam::saveAll(ofstream& examsout) {
strcpy(save.filename, filename);
strcpy(save.name, name);
studentnum = items.size();
save.studentnum = studentnum;
ofstream obin(filename, ios::out, ios::binary);
Item tmp;
for (auto i = items.begin(); i < items.end(); i++) {
tmp = *i;
obin.write((char*)&tmp, sizeof(Item));
}
obin.close();
examsout.write((char*)&this->save, sizeof(Examsave));
}
void Exam::dspHeader() {
cout << setw(20) << "Ãû³Æ" << setw(15) << "ѧÉúÊý" << endl;
}
void Exam::dsp() const {
cout << setw(20) << name << setw(15) << studentnum << endl;
}
void Exam::dspName() const {
cout << name;
}
void Exam::dspName(int w) const {
cout << setw(w) << name;
}
void Exam::dspItems() const {
for (auto i = items.begin(); i < items.end(); i++) {
i->dsp();
cout << setw(6) << distance(items.begin(), i) + 1 << endl;
}
}
void Exam::toCsvItems(ofstream& csv) const {
for (auto i = items.begin(); i < items.end(); i++) {
i->toCsv(csv);
csv << distance(items.begin(), i) + 1 << endl;
}
}
bool Exam::itemExists(long long int studentNo) const {
for (auto i = items.begin(); i < items.end(); i++) {
if (i->getStuNo()== studentNo) {
return true;
}
}
return false;
}
bool Exam::rmvItem(long long int studentNo) {
for (auto i = items.begin(); i < items.end(); i++) {
if (i->getStuNo() == studentNo) {
items.erase(i);
studentnum--;
return true;
}
}
return false;
}
void Exam::changeName(char name[]) {
strcpy(this->name, name);
}
const Item* Exam::StudentInquiry(long long int studentNo) const{
for (auto item = items.begin(); item < items.end(); item++) {
if (item->getStuNo() == studentNo) {
return &(*item);
}
}
return nullptr;
}
int Exam::getStuRanking(const Item& item) {
for (auto i = items.begin(); i < items.end(); i++) {
if (i->stuNoEqual(item)) {
return distance(items.begin(), i) + 1;
}
}
return -1;
}
void Exam::rm() const {
remove(filename);
}

47
Exam.h Normal file
View File

@ -0,0 +1,47 @@
#pragma once
#include<algorithm>
#include<fstream>
#include<iomanip>
#include<iostream>
#include<string>
#include<vector>
#include"Item.h"
using namespace std;
struct Examsave {
int studentnum;
char name[100];
char filename[100];
};
class Exam {
public:
Exam(Examsave* insave);
Exam(char inname[]);
void saveAll(ofstream& examsout);
void addItem(long long int studentNo, double score[9]);
void addItem(const Item& item);
bool rmvItem(long long int studentNo);
static void dspHeader();
void dsp() const;
void dspName() const;
void dspName(int w) const;
void dspItems() const;
void toCsvItems(ofstream& csv) const;
bool itemExists(long long int studentNo) const;
void changeName(char name[]);
const Item* StudentInquiry(long long int studentNo) const;
int getStuRanking(const Item& item);
void rm() const;
virtual ~Exam(){};
private:
vector<Item> items;
struct Examsave save;
int studentnum;
char name[100];
char filename[100];
};

122
Item.cpp Normal file
View File

@ -0,0 +1,122 @@
#include"Item.h"
#include"Student.h"
#include"Manager.h"
using namespace std;
extern Manager mainManager;
Item::Item(long long int studentNo, double inscore[]) {
sum = 0;
for (int i = 0; i < 9; i++) {
score[i] = inscore[i];
sum = sum + score[i];
}
this->studentNo = studentNo;
}
Item::Item() {
studentNo = -1;
}
bool Item::operator<(const Item& i) const {
if (this->sum < i.sum) {
return true;
}
else if (this->sum > i.sum) {
return false;
}
else if (this->studentNo < i.sum) {
return true;
}
else {
return false;
}
}
bool Item::operator>(const Item& i) const {
if (this->sum < i.sum) {
return false;
}
else if (this->sum > i.sum) {
return true;
}
else if (this->studentNo < i.sum) {
return false;
}
else {
return true;
}
}
long long int Item::getStuNo() const {
return studentNo;
}
bool Item::stuNoEqual(const Item& i) const {
if (this->studentNo == i.studentNo) {
return true;
}
else {
return false;
}
}
void Item::dspHeader() {
Student::dspHeader();
cout << setw(5) << "数学" << setw(5) << "语文" << setw(5) << "英语" << setw(5) << "物理" << setw(5) << "化学" << setw(5) << "生物" << setw(5) << "历史" << setw(5) << "政治" << setw(5) << "地理" << setw(6) << "总分";
}
void Item::dspHeader(int w) {
cout << setw(5) << "数学" << setw(5) << "语文" << setw(5) << "英语" << setw(5) << "物理" << setw(5) << "化学" << setw(5) << "生物" << setw(5) << "历史" << setw(5) << "政治" << setw(5) << "地理" << setw(6) << "总分";
}
void Item::dsp() const {
Student* stup = mainManager.searchByNo(this->studentNo);
Student stu;
if (stup == nullptr) {
stu = Student(this->studentNo);
}
else {
stu = *stup;
}
stu.dsp();
cout << setw(5) << score[0] << setw(5) << score[1] << setw(5) << score[2] << setw(5) << score[3] << setw(5) << score[4] << setw(5) << score[5] << setw(5) << score[6] << setw(5) << score[7] << setw(5) << score[8] << setw(6) << sum;
}
void Item::dsp(int w) const {
cout << setw(5) << score[0] << setw(5) << score[1] << setw(5) << score[2] << setw(5) << score[3] << setw(5) << score[4] << setw(5) << score[5] << setw(5) << score[6] << setw(5) << score[7] << setw(5) << score[8] << setw(6) << sum;
}
void Item::toCsvHeader(ofstream& csv) {
Student::toCsvHeader(csv);
csv << "数学," << "语文," << "英语," << "物理," << "化学," << "生物," << "历史," << "政治," << "地理," << "总分,";
}
void Item::toCsv(ofstream& csv) const {
Student* stup = mainManager.searchByNo(this->studentNo);
Student stu;
if (stup == nullptr) {
stu = Student(this->studentNo);
}
else {
stu = *stup;
}
stu.toCsv(csv);
csv << score[0] << "," << score[1] << "," << score[2] << "," << score[3] << "," << score[4] << "," << score[5] << "," << score[6] << "," << score[7] << "," << score[8] << "," << sum << ",";
}
Item::Item(ifstream& csv, int stuNoColumn,int scoreColumn[]) {
string line, tmp;
vector<string> tmpvector;
sum = 0;
if (!getline(csv,line)) {
studentNo = -1;
return;
}
stringstream linestream(line);
while (getline(linestream, tmp, ',')) {
tmpvector.push_back(tmp);
};
try {
studentNo = stoi(tmpvector.at(stuNoColumn-1));
}
catch (const exception& e) {
studentNo = 0;
}
for (auto i = 0; i < 9; i++) {
try {
score[i] = stoi(tmpvector.at(scoreColumn[i]-1));
}
catch (const exception& e) {
score[i] = 0;
}
sum += score[i];
}
}

32
Item.h Normal file
View File

@ -0,0 +1,32 @@
#pragma once
#include<algorithm>
#include<fstream>
#include<iomanip>
#include<iostream>
#include<sstream>
#include<string>
#include<vector>
using namespace std;
class Item {
public:
Item(long long int studentNo, double inscore[]);
Item(ifstream& csv, int stuNoColumn, int scoreColumn[]);
Item();
bool operator>(const Item& i) const;
bool operator<(const Item& i) const;
long long int getStuNo() const;
bool stuNoEqual(const Item& i) const;
static void dspHeader();
static void dspHeader(int w);
void dsp() const;
void dsp(int w) const;
static void toCsvHeader(ofstream& csv);
void toCsv(ofstream& csv) const;
virtual ~Item() {}
private:
long long int studentNo;
double score[9];
double sum;
};

907
Manager.cpp Normal file
View File

@ -0,0 +1,907 @@
#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();
}

67
Manager.h Normal file
View File

@ -0,0 +1,67 @@
#pragma once
#include<fstream>
#include<iomanip>
#include<iostream>
#include<string>
#include<vector>
#include<windows.h>
#include"Student.h"
#include"Exam.h"
using namespace std;
class Manager {
public:
Manager();
void mainLoop();
void goBack();
void centeredPrint(const string& content);
Student* searchByNo(long long int studentNo);
//status 0
void welcomePage();
//status 1
void stuPage();
//status 11
void stuDspPage();
//status 12
void stuAddPage();
//status 13
void stuSearchPage();
//status 14
void stuEdtRmvPage();
//status 15
void stuExportPage();
//status 16
void stuImportPage();
//status 2
void examPage();
//status 21
void examAddPage();
//status 22
void examChoosePage();
//status 23
void examSubPage();
//status 231
void examViewPage();
//status 232
void examExportPage();
//status 233
void examAddRowPage();
//status 234
void examDelRowPage();
//status 235
void examNamePage();
//status 236
void examImportPage();
//status 237
void examRmvPage();
//status 3
void stuPfmPage();
virtual ~Manager();
private:
int status = 0;
int ExamNum = 0, StudentNum = 0;
vector<Student> Students;
vector<std::shared_ptr<Exam>> Exams;
vector<std::shared_ptr<Exam>>::iterator currentExam = Exams.begin();
};

124
Student.cpp Normal file
View File

@ -0,0 +1,124 @@
#include"Student.h"
#include"Manager.h"
#pragma warning(disable:4996)
using namespace std;
extern Manager mainManager;
Student::Student(int year, int selectionNo, int classNo, char name[]) :year(year), selectionNo(selectionNo), classNo(classNo), serialNo(serialNo) {
strcpy_s(this->name, name);
studentNo = infoToNo(year, selectionNo, classNo);
serialNo = studentNo % 100;
}
Student::Student(long long int studentNo) {
this->studentNo = studentNo;
strcpy(this->name, "查无此人");
year = 0;
selectionNo = 0;
classNo = 0;
serialNo = 0;
}
Student::Student(ifstream& csv, int yearColumn, int clsColumn, int slcColumn,int nameColumn) {
string line, tmp;
vector<string> tmpvector;
if (!getline(csv, line)) {
studentNo = -1;
return;
}
stringstream linestream(line);
while (getline(linestream, tmp, ',')) {
tmpvector.push_back(tmp);
};
try {
year = stoi(tmpvector.at(yearColumn - 1));
}
catch (const exception& e) {
year = 0;
}
try {
classNo = stoi(tmpvector.at(clsColumn - 1));
}
catch (const exception& e) {
classNo = 0;
}
try {
selectionNo = stoi(tmpvector.at(slcColumn - 1));
}
catch (const exception& e) {
selectionNo = 0;
}
strcpy(this->name, tmpvector.at(nameColumn - 1).c_str());
if (year != 0 && classNo != 0 && selectionNo != 0) {
studentNo = infoToNo(year, selectionNo, classNo);
serialNo = studentNo % 100;
}
else {
studentNo = 0;
serialNo = 0;
}
}
void Student::dspHeader() {
cout << setw(10) << "姓名" << setw(12) << "学号" << setw(10) << "入学年份" << setw(5) << "班级" << setw(5) << "选科";
}
void Student::dsp() const {
cout << setw(10) << name << setw(12) << studentNo << setw(10) << year << setw(5) << classNo << setw(5) << selectionNo;
}
void Student::toCsvHeader(ofstream& csv) {
csv<< "姓名,"<< "学号,"<< "入学年份,"<< "班级," << "选科,";
}
void Student::toCsv (ofstream& csv) const {
csv << name << ',' << studentNo << ',' << year << ',' << classNo << ',' << selectionNo << ',';
}
void Student::setInfo(int year, int selectionNo, int classNo, char name[]) {
this->year = year;
this->selectionNo = selectionNo;
this->classNo = classNo;
strcpy(this->name, name);
}
bool Student::stuNoEqual(long long int studentNo) const {
if (this->studentNo == studentNo) {
return true;
}
else {
return false;
}
}
bool Student::slcNoEqual(int selectionNo) const {
if (this->selectionNo == selectionNo) {
return true;
}
else {
return false;
}
}
bool Student::clsNoEqual(int classNo) const {
if (this->classNo == classNo) {
return true;
}
else {
return false;
}
}
bool Student::nameEqual(char name[]) const {
if (strcmp(this->name, name) == 0) {
return true;
}
else {
return false;
}
}
bool Student::yearEqual(int year) const {
if (this->year == year) {
return true;
}
else {
return false;
}
}
long long int Student::infoToNo(int year, int selectionNo, int classNo) {
long long int initNo = year * 1000000 + selectionNo * 10000 + classNo * 100 + 1;
for (auto i = initNo; i < initNo + 99; i++) {
if (mainManager.searchByNo(i) == nullptr) {
return i;
}
}
return -1;
}

36
Student.h Normal file
View File

@ -0,0 +1,36 @@
#pragma once
#include<fstream>
#include<iomanip>
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Student {
public:
Student(int year, int selectionNo, int classNo, char name[]);
Student(long long int studentNo);
Student(ifstream& csv, int yearColumn, int clsColumn, int slcColumn,int nameColumn);
Student(){}
void setInfo(int year, int selectionNo, int classNo, char name[]);
bool stuNoEqual(long long int studentNo) const;
bool slcNoEqual(int selectionNo) const;
bool clsNoEqual(int classNo) const;
bool yearEqual(int year) const;
bool nameEqual(char name[]) const;
static void dspHeader();
void dsp() const;
static void toCsvHeader(ofstream& csv);
void toCsv(ofstream& csv) const;
static long long int infoToNo(int year,int selectionNo, int classNo);
virtual ~Student(){};
private:
long long int studentNo;
char name[100];
int year;
int selectionNo;
int classNo;
int serialNo;
};

8
main.cpp Normal file
View File

@ -0,0 +1,8 @@
#include"Exam.h"
#include"Student.h"
#include"Manager.h"
Manager mainManager;
using namespace std;
int main() {
mainManager.mainLoop();
}