From 2ba7cbd7a52ee6380b1eaf1a27145486e4caa363 Mon Sep 17 00:00:00 2001 From: zyx <1029606625@qq.com> Date: Mon, 4 Jul 2022 22:17:38 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=A8=E6=96=87=E4=BB=B6=E8=AF=BB?= =?UTF-8?q?=E5=86=99=E5=87=BD=E6=95=B0=EF=BC=8C=E6=B7=BB=E5=8A=A0=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=EF=BC=8C=E5=AE=8C=E5=96=84=E4=BB=A3=E7=A0=81=EF=BC=8C?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=B5=8B=E8=AF=95=E6=BA=90=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- Course.cpp | 3 ++ CourseDAO.h | 41 ++++++++++++++++ CourseDAOImpl.cpp | 6 +-- DBCUtils.cpp | 40 ++++----------- DBCUtils.h | 16 +++++- Grade.cpp | 9 ++-- GradeDAO.h | 107 ++++++++++++++++++++++++++++++++++++++++ GradeDAOImpl.cpp | 20 ++++---- Menu.cpp | 116 ++++++++++++++++++++++++++------------------ Menu.h | 98 +++++++++++++++++++++++++++++++++++++ MenuUtils.cpp | 19 -------- MenuUtils.h | 11 ++++- SAS.vcxproj | 3 +- SAS.vcxproj.filters | 9 ++-- StringUtils.cpp | 56 +++++++++++++++++++++ StringUtils.h | 29 +++++++++++ Student.cpp | 3 ++ StudentDAO.h | 48 ++++++++++++++++++ StudentDAOImpl.cpp | 6 +-- Test.cpp | 100 -------------------------------------- main.cpp | 7 ++- 22 files changed, 521 insertions(+), 229 deletions(-) create mode 100644 StringUtils.cpp create mode 100644 StringUtils.h delete mode 100644 Test.cpp diff --git a/.gitignore b/.gitignore index 9491a2f..4f5dc06 100644 --- a/.gitignore +++ b/.gitignore @@ -360,4 +360,5 @@ MigrationBackup/ .ionide/ # Fody - auto-generated XML schema -FodyWeavers.xsd \ No newline at end of file +FodyWeavers.xsd +/data diff --git a/Course.cpp b/Course.cpp index 1cfa42f..1772099 100644 --- a/Course.cpp +++ b/Course.cpp @@ -1,3 +1,6 @@ +/* +* 课程表DAO +*/ #ifndef COURSE_CPP #define COURSE_CPP diff --git a/CourseDAO.h b/CourseDAO.h index 9328916..4354dbe 100644 --- a/CourseDAO.h +++ b/CourseDAO.h @@ -1,3 +1,6 @@ +/* +* 课程表数据库操作接口 +*/ #ifndef COURSE_DAO_H #define COURSE_DAO_H @@ -7,11 +10,49 @@ #include #include"Course.cpp" +/* +* 向数据库添加课程 +* @param connection 数据库连接 +* @param course 待添加的课程对象 +*/ void addCourse(_ConnectionPtr connection, Course course); + +/* +* 删除课程 +* @param connection 数据库连接 +* @param id 课程号 +*/ void deleteCourse(_ConnectionPtr connection, string id); + +/* +* 修改课程名 +* @param connection 数据库连接 +* @param id 课程号 +* @param name 课程名 +*/ void updateCourseName(_ConnectionPtr connection, string id, string name); + +/* +* 根据课程号获取课程对象 +* @param connection 数据库连接 +* @param id 课程号 +* @return Course* course对象指针 +*/ Course* getCourseById(_ConnectionPtr connection, string id); + +/* +* 根据课程名获取课程对象 +* @param connection 数据库连接 +* @param name 课程名 +* @return Course* course对象指针 +*/ Course* getCourseByName(_ConnectionPtr connection, string name); + +/* +* 获取所有课程对象 +* @param connection 数据库连接 +* @return vector* 以Course对象为元素的vector数组指针 +*/ std::vector* getAllCourse(_ConnectionPtr connection); #endif // !COURSE_DAO_H \ No newline at end of file diff --git a/CourseDAOImpl.cpp b/CourseDAOImpl.cpp index c3040d2..a84604f 100644 --- a/CourseDAOImpl.cpp +++ b/CourseDAOImpl.cpp @@ -22,7 +22,7 @@ void updateCourseName(_ConnectionPtr connection, string id, string name) { Course* getCourseById(_ConnectionPtr connection, string id) { string sql = "select * from course where id = '" + id + "'"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 Course* course = new Course(); course->setId((char*)(_bstr_t)record->Fields->GetItem("id")->Value); @@ -33,7 +33,7 @@ Course* getCourseById(_ConnectionPtr connection, string id) { Course* getCourseByName(_ConnectionPtr connection, string name) { string sql = "select * from course where name = '" + name + "'"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 Course* course = new Course(); course->setId((char*)(_bstr_t)record->Fields->GetItem("id")->Value); @@ -44,7 +44,7 @@ Course* getCourseByName(_ConnectionPtr connection, string name) { std::vector* getAllCourse(_ConnectionPtr connection) { string sql = "select * from course"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 std::vector* v = new std::vector(); Course* course; diff --git a/DBCUtils.cpp b/DBCUtils.cpp index a088ae5..e113bca 100644 --- a/DBCUtils.cpp +++ b/DBCUtils.cpp @@ -3,12 +3,12 @@ bool getConnection(std::string& pwd, _ConnectionPtr& connection) { bool isPwdTrue = false; _bstr_t strConnect; - if (!pwd.empty()) { + if (!pwd.empty()) {//密码非空,使用SQL Server身份验证 try { std::string con = "Provider=SQLOLEDB.1;Password=" + pwd + "; Persist Security Info = True; User ID = sa; Initial Catalog = stuAdminSystem; Data Source = LAPTOP-4DMOD6O5"; strConnect = con.c_str(); connection->Open(strConnect, "", "", NULL); - isPwdTrue = true; + isPwdTrue = true;//密码正确,连接成功 wprintf(L"登录成功!\n"); return true; } @@ -16,16 +16,16 @@ bool getConnection(std::string& pwd, _ConnectionPtr& connection) { wprintf(L"The application throws the error: %s\n", (wchar_t*)err.ErrorMessage()); wprintf(L"Description = %s\n", (wchar_t*)err.Description()); } - if (!isPwdTrue) { + if (!isPwdTrue) {//密码错误,连接失败(打开连接失败,跳出try块执行) wprintf(L"密码错误!"); return false; } } - else { + else {//密码为空,使用Windows 身份验证 try { strConnect = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=stuAdminSystem;Data Source=LAPTOP-4DMOD6O5"; connection->Open(strConnect, "", "", NULL); - isPwdTrue = true; + isPwdTrue = true;//验证成功,连接成功 wprintf(L"登录成功!\n"); return true; } @@ -33,41 +33,19 @@ bool getConnection(std::string& pwd, _ConnectionPtr& connection) { wprintf(L"The application throws the error: %s\n", (wchar_t*)err.ErrorMessage()); wprintf(L"Description = %s\n", (wchar_t*)err.Description()); } - if (!isPwdTrue) { + if (!isPwdTrue) {//验证失败,连接失败(打开连接失败,跳出try块执行) wprintf(L"验证失败!"); return false; } } + return false; } void getSqlType(std::string& sql, std::string& comType) { - int len = sql.length(); - for (int i = 0; i < len; i++) {//判断sql语句类型 + size_t len = sql.length(); + for (size_t i = 0; i < len; i++) {//获取SQL语句的类别 if (sql[i] != ' ') comType += isupper(sql[i]) ? (sql[i] - 32) : sql[i]; else return; } -} - -void showRecordInfo(_RecordsetPtr& recordSet) { - COORD pos = { 0,0 }; - for (long i = 0; i < recordSet->Fields->Count; i++) { - SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); - wprintf(L"%s", (wchar_t*)recordSet->Fields->GetItem(i)->Name); - pos.X += (short)recordSet->Fields->GetItem(i)->DefinedSize % 16 + 4; - } - for (; !recordSet->EndOfFile; recordSet->MoveNext()) { - pos.X = 0; - pos.Y++; - for (long i = 0; i < recordSet->Fields->Count; i++) { - SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); - if (recordSet->Fields->GetItem(i)->Value.vt == VT_NULL) { - wprintf(L"Null"); - } - else { - wprintf(L"%s", (wchar_t*)(_bstr_t)recordSet->Fields->GetItem(i)->Value); - } - pos.X += (short)recordSet->Fields->GetItem(i)->DefinedSize % 16 + 4; - } - } } \ No newline at end of file diff --git a/DBCUtils.h b/DBCUtils.h index 3adaffa..9144d79 100644 --- a/DBCUtils.h +++ b/DBCUtils.h @@ -1,3 +1,6 @@ +/* +* 数据库连接工具函数接口 +*/ #ifndef DBCUTILS_H #define DBCUTILS_H @@ -8,8 +11,19 @@ #include // setlocale #include +/* +* 获取连接 +* @param pwd 待验证的密码 +* @param connection 待获取的连接对象 +* @return bool 密码是否正确 / 是否获取到连接 +*/ bool getConnection(std::string& pwd, _ConnectionPtr& connection); + +/* +* 获取sql语句种类 +* @param sql 待获取语句类别的SQL语句 +* @param comType SQL语句类别 +*/ void getSqlType(std::string& sql, std::string& comType); -void showRecordInfo(_RecordsetPtr& recordSet); #endif // !DBCUTILS_H \ No newline at end of file diff --git a/Grade.cpp b/Grade.cpp index dab3424..eab0573 100644 --- a/Grade.cpp +++ b/Grade.cpp @@ -1,3 +1,6 @@ +/* +* 成绩表DAO +*/ #ifndef GRADE_CPP #define GRADE_CPP @@ -25,9 +28,9 @@ public: return stuId + "\t" + courseId + "\t" + grade; } private: - string stuId; - string courseId; - string grade; + string stuId;//学号 + string courseId;//课程号 + string grade;//成绩 }; #endif // !GRADE_CPP \ No newline at end of file diff --git a/GradeDAO.h b/GradeDAO.h index 9ce4289..d1c08af 100644 --- a/GradeDAO.h +++ b/GradeDAO.h @@ -1,3 +1,6 @@ +/* +* 成绩表数据库操作接口 +*/ #ifndef GRADE_DAO_H #define GRADE_DAO_H @@ -7,21 +10,125 @@ #include #include"Grade.cpp" +/* +* 向数据库添加成绩 +* @param connection 数据库连接 +* @param grade 待添加的成绩对象 +*/ void addGrade(_ConnectionPtr connection, Grade grade); + +/* +* 删除某人的某科成绩 +* @param connection 数据库连接 +* @param stuId 学号 +* @param courseId 课程号 +*/ void deleteOnesGrade(_ConnectionPtr connection, string stuId,string courseId); + +/* +* 删除某人所有成绩 +* @param connection 数据库连接 +* @param stuId 学号 +*/ void deleteGradeByStuId(_ConnectionPtr connection, string stuId); + +/* +* 删除某科的所有成绩 +* @param connection 数据库连接 +* @param courseId 待删除课程的课程号 +*/ void deleteGradeByCourseId(_ConnectionPtr connection, string courseId); + +/* +* 更新某人的某科成绩 +* @param connection 数据库连接 +* @param stuId 学号 +* @param courseId 课程号 +* @param grade 成绩 +*/ void updateOnesGrade(_ConnectionPtr connection, string stuId, string courseId, string grade); + +/* +* 获取某人某科成绩 +* @param connection 数据库连接 +* @param stuId 学号 +* @param courseId 课程号 +* @return Grade* grade对象指针 +*/ Grade* getOnesGrade(_ConnectionPtr connection, string stuId, string courseId); + +/* +* 获取某人的所有成绩 +* @param connection 数据库连接 +* @param stuId 学号 +* @return vector* 以Grade对象为元素的vector数组指针 +*/ std::vector* getGradeByStuId(_ConnectionPtr connection, string stuId); + +/* +* 获取某课程的所有成绩记录 +* @param connection 数据库连接 +* @param coursesId 课程号 +* @return vector* 以Grade对象为元素的vector数组指针 +*/ std::vector* getGradeByCourseId(_ConnectionPtr connection, string courseId); + +/* +* 获取某班级的所有成绩记录 +* @param connection 数据库连接 +* @param stuClass 班级 +* @return vector* 以Grade对象为元素的vector数组指针 +*/ std::vector* getGradeByStuClass(_ConnectionPtr connection, string stuClass); + +/* +* 获取所有成绩记录 +* @param connection 数据库连接 +* @return vector* 以Grade对象为元素的vector数组指针 +*/ std::vector* getAllGrade(_ConnectionPtr connection); +/* +* 获取某人的平均成绩 +* @param connection 数据库连接 +* @param stuId 学号 +* @return double 平均成绩 +*/ double getOnesAvgGrade(_ConnectionPtr connection, string stuId); + +/* +* 获取某人的总成绩 +* @param connection 数据库连接 +* @param stuId 学号 +* @return double 总成绩 +*/ double getOnesAllGrade(_ConnectionPtr connection, string stuId); + +/* +* 获取某班级某科的平均成绩 +* @param connection 数据库连接 +* @param stuClass 班级 +* @param courseName 课程名 +* @return double 班级某科平均成绩 +*/ double getClassAvgGrade(_ConnectionPtr connection, string stuClass, string courseName); + +/* +* 获取某班级某科的最高成绩 +* @param connection 数据库连接 +* @param stuClass 班级 +* @param courseName 课程名 +* @return double 班级某科最高成绩 +*/ double getClassMaxGrade(_ConnectionPtr connection, string stuClass, string courseName); + +/* +* 获取某班级某科的最低成绩 +* @param connection 数据库连接 +* @param stuClass 班级 +* @param courseName 课程名 +* @return double 班级某科最低成绩 +*/ double getClassMinGrade(_ConnectionPtr connection, string stuClass, string courseName); #endif // !GRADE_DAO_H diff --git a/GradeDAOImpl.cpp b/GradeDAOImpl.cpp index 023db7e..de10edb 100644 --- a/GradeDAOImpl.cpp +++ b/GradeDAOImpl.cpp @@ -35,7 +35,7 @@ void updateOnesGrade(_ConnectionPtr connection, string stuId, string courseId, s Grade* getOnesGrade(_ConnectionPtr connection, string stuId,string courseId) { string sql = "select * from grade where stuId = '" + stuId + "\' and courseId = \'" + courseId + "'"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 Grade* grade = new Grade(); grade->setStuId((char*)(_bstr_t)record->Fields->GetItem("stuId")->Value); @@ -47,7 +47,7 @@ Grade* getOnesGrade(_ConnectionPtr connection, string stuId,string courseId) { std::vector* getGradeByStuId(_ConnectionPtr connection, string stuId) { string sql = "select * from grade where stuId = '" + stuId + "'"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 std::vector* v = new std::vector(); Grade* grade; @@ -64,7 +64,7 @@ std::vector* getGradeByStuId(_ConnectionPtr connection, string stuId) { std::vector* getGradeByCourseId(_ConnectionPtr connection, string courseId) { string sql = "select * from grade where courseId = '" + courseId + "'"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 std::vector* v = new std::vector(); Grade* grade; @@ -81,7 +81,7 @@ std::vector* getGradeByCourseId(_ConnectionPtr connection, string courseI std::vector* getGradeByStuClass(_ConnectionPtr connection, string stuClass) { string sql = "select * from grade where stuId in(select id from student where stuClass = '" + stuClass + "')"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 std::vector* v = new std::vector(); Grade* grade; @@ -98,7 +98,7 @@ std::vector* getGradeByStuClass(_ConnectionPtr connection, string stuClas std::vector* getAllGrade(_ConnectionPtr connection) { string sql = "select * from grade"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 std::vector* v = new std::vector(); Grade* grade; @@ -115,7 +115,7 @@ std::vector* getAllGrade(_ConnectionPtr connection) { double getOnesAvgGrade(_ConnectionPtr connection, string stuId) { string sql = "select count(*) cnt,sum(grade) all_grade from grade where stuId = '" + stuId + "'"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 int cnt = atoi((char*)(_bstr_t)record->Fields->GetItem("cnt")->Value); double all_grade = atof((char*)(_bstr_t)record->Fields->GetItem("all_grade")->Value); @@ -125,7 +125,7 @@ double getOnesAvgGrade(_ConnectionPtr connection, string stuId) { double getOnesAllGrade(_ConnectionPtr connection, string stuId) { string sql = "select sum(grade) all_grade from grade where stuId = '" + stuId + "'"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 return atof((char*)(_bstr_t)record->Fields->GetItem("all_grade")->Value); } @@ -134,7 +134,7 @@ double getClassAvgGrade(_ConnectionPtr connection, string stuClass, string cours string sql = "select avg(grade) avg_grade from grade where stuId in (select id from student where stuClass = '" + stuClass + "') "; sql += "and courseId in (select id from course where name = '" + courseName + "')"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 return atof((char*)(_bstr_t)record->Fields->GetItem("avg_grade")->Value); } @@ -143,7 +143,7 @@ double getClassMaxGrade(_ConnectionPtr connection, string stuClass, string cours string sql = "select max(grade) max_grade from grade where stuId in (select id from student where stuClass = '" + stuClass + "') "; sql += "and courseId in (select id from course where name = '" + courseName + "')"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 return atof((char*)(_bstr_t)record->Fields->GetItem("max_grade")->Value); } @@ -152,7 +152,7 @@ double getClassMinGrade(_ConnectionPtr connection, string stuClass, string cours string sql = "select min(grade) min_grade from grade where stuId in (select id from student where stuClass = '" + stuClass + "') "; sql += "and courseId in (select id from course where name = '" + courseName + "')"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 return atof((char*)(_bstr_t)record->Fields->GetItem("min_grade")->Value); } \ No newline at end of file diff --git a/Menu.cpp b/Menu.cpp index e5a596c..462485f 100644 --- a/Menu.cpp +++ b/Menu.cpp @@ -19,34 +19,34 @@ void mainMenu(_ConnectionPtr connection) { checkOptInput(opt, 0, 9); switch (opt) { - case 1: + case 1://显示所有学生 showAllStudent(connection); break; - case 2: + case 2://增加学生 insertStudent(connection); break; - case 3: + case 3://删除学生 deleteStudent(connection); break; - case 4: + case 4://修改学生 changeStudent(connection); break; - case 5: + case 5://从文件导入学生信息 importData(connection); break; - case 6: + case 6://导出学生信息到文件 exportData(connection); break; - case 7: + case 7://学生成绩管理 studentGradeMenu(connection); break; - case 8: + case 8://课程管理 courseMenu(connection); break; - case 9: + case 9://高级功能 advancedFunction(connection); break; - default: + default://退出程序 exit(EXIT_SUCCESS); } printf("\n"); @@ -83,7 +83,7 @@ void studentGradeMenu(_ConnectionPtr connection) { string stuId, courseId; string stuClass, courseName; double grade = -1; - int size; + size_t size; vector* v; switch (opt) { case 1://输入学生成绩 @@ -141,7 +141,7 @@ void studentGradeMenu(_ConnectionPtr connection) { } size = v->size(); cout << "学号\t" << "课程名\t" << "成绩\n"; - for (int i = 0; i < size; i++) { + for (size_t i = 0; i < size; i++) { cout << (*v)[i].toString() << "\n"; } break; @@ -184,7 +184,7 @@ void studentGradeExternMenu(_ConnectionPtr connection) { string stuId, courseId; string stuClass, courseName; double grade = -1; - int size; + size_t size; vector* v; Grade* gra; Course* course; @@ -266,7 +266,7 @@ void studentGradeExternMenu(_ConnectionPtr connection) { } size = v->size(); cout << "学号\t" << "课程名\t" << "成绩\n"; - for (int i = 0; i < size; i++) { + for (size_t i = 0; i < size; i++) { cout << (*v)[i].toString() << "\n"; } break; @@ -285,7 +285,7 @@ void studentGradeExternMenu(_ConnectionPtr connection) { } size = v->size(); cout << "学号\t" << "课程名\t" << "成绩\n"; - for (int i = 0; i < size; i++) { + for (size_t i = 0; i < size; i++) { cout << (*v)[i].toString() << "\n"; } break; @@ -297,7 +297,7 @@ void studentGradeExternMenu(_ConnectionPtr connection) { } size = v->size(); cout << "学号\t" << "课程名\t" << "成绩\n"; - for (int i = 0; i < size; i++) { + for (size_t i = 0; i < size; i++) { cout << (*v)[i].toString() << "\n"; } break; @@ -329,7 +329,7 @@ void courseMenu(_ConnectionPtr connection) { printf("\n"); - int size; + size_t size; string courseId, courseName; vector* v; switch (opt) { @@ -363,7 +363,7 @@ void courseMenu(_ConnectionPtr connection) { } size = v->size(); cout << "课程号\t" << "课程名\n"; - for (int i = 0; i < size; i++) { + for (size_t i = 0; i < size; i++) { cout << (*v)[i].toString() << "\n"; } break; @@ -386,33 +386,37 @@ void advancedFunction(_ConnectionPtr connection) { _RecordsetPtr record(_uuidof(Recordset)); string sql; + //重置cin并清空缓冲区 cin.clear(); while (cin.get() != '\n'); + while (true) { try { + //输出提示符 wprintf(L"sql>"); - //获取sql命令及种类 + //获取SQL命令 getline(cin, sql); - while (sql == "" || sql[sql.size() - 1] != ';') { + while (sql == "" || trim(sql)[trim(sql).size() - 1] != ';') {//获取多行的SQL语句 wprintf(L" >"); string tmp; getline(cin, tmp); sql += " " + tmp; } + //去除首尾空格及中间多余空格 + sql = reduce(sql); + //获取SQL语句类别 string comType = ""; getSqlType(sql, comType); - //执行sql命令 + //执行SQL命令 if (comType == "select") {//查询 record = connection->Execute(sql.c_str(), NULL, (long)0); for (long i = 0; i < record->Fields->Count; i++) wprintf(L"%s\t", (wchar_t*)record->Fields->GetItem(i)->Name); printf("\n"); wprintf(L"%s", (wchar_t*)record->GetString(adClipString, long(-1), "\t", "\n", "Null")); - //showRecordInfo(record); - }else if (comType == "exit" || comType == "exit;") { - system("pause"); + }else if (comType == "exit" || comType == "exit;") {//退出 break; - }else { + }else {//其他类型 connection->Execute(sql.c_str(), NULL, (long)0); } printf("\n"); @@ -433,9 +437,9 @@ void showAllStudent(_ConnectionPtr connection) { return; } - int size = vs->size(); + size_t size = vs->size(); printf("学号\t姓名\t性别\t班级\t状态\n"); - for (int i = 0; i < size; i++) { + for (size_t i = 0; i < size; i++) { cout << (*vs)[i].toString() << "\n"; } } @@ -446,6 +450,11 @@ void insertStudent(_ConnectionPtr connection) { string str; printf("请输入学号:"); cin >> str; + Student* checkExist = getStudentById(connection, str); + if (checkExist != NULL) { + printf("该学生已存在!\n"); + return; + } stu->setId(str); printf("请输入姓名:"); cin >> str; @@ -487,18 +496,18 @@ void changeStudent(_ConnectionPtr connection) { return; } - printf("请选择修改 班级(0) / 学生状态(1):"); + printf("请选择修改 班级(0) / 学生状态(1):\n"); int opt = -1; checkOptInput(opt, 0, 1); string input; switch (opt) { - case 0: + case 0://修改班级 printf("\n请输入新班级:"); cin >> input; updateStudentClass(connection,id,input); break; - default: + default://修改状态 printf("\n请输入新状态:"); cin >> input; updateStudentStatus(connection,id, input); @@ -509,6 +518,10 @@ void changeStudent(_ConnectionPtr connection) { void exportData(_ConnectionPtr connection) { while (true) { try { + // 文件夹不存在则创建文件夹 + if (_access("./data", 0) == -1) { + _mkdir("./data"); + } system("cls"); printf("1.导出学生信息\n"); printf("2.导出课程信息\n"); @@ -548,13 +561,13 @@ void exportData(_ConnectionPtr connection) { } void exportStudentData(_ConnectionPtr connection) { - ofstream outFile("student.txt", ios::out); + ofstream outFile("./data/student.txt", ios::out); if (!outFile.is_open()) { printf("导出student.txt文件失败!\n"); return; } - int size; + size_t size; vector* vs; vs = getAllStudent(connection); if (vs == NULL) { @@ -564,21 +577,22 @@ void exportStudentData(_ConnectionPtr connection) { } outFile << "学号\t姓名\t性别\t班级\t状态\n"; size = vs->size(); - for (int i = 0; i < size; i++) { - outFile << (*vs)[i].toString() << "\n"; + for (size_t i = 0; i < size; i++) { + outFile << (*vs)[i].toString(); + if (i != (size - 1)) outFile << "\n"; } printf("成功导出student.txt文件!\n"); outFile.close(); } void exportCourseData(_ConnectionPtr connection) { - ofstream outFile("course.txt", ios::out); + ofstream outFile("./data/course.txt", ios::out); if (!outFile.is_open()) { printf("导出course.txt文件失败!\n"); return; } - int size; + size_t size; vector* vc; vc = getAllCourse(connection); if (vc == NULL) { @@ -588,21 +602,22 @@ void exportCourseData(_ConnectionPtr connection) { } outFile << "课程号\t课程名\n"; size = vc->size(); - for (int i = 0; i < size; i++) { - outFile << (*vc)[i].toString() << "\n"; + for (size_t i = 0; i < size; i++) { + outFile << (*vc)[i].toString(); + if (i != (size - 1)) outFile << "\n"; } printf("成功导出course.txt文件!\n"); outFile.close(); } void exportGradeData(_ConnectionPtr connection) { - ofstream outFile("grade.txt", ios::out); + ofstream outFile("./data/grade.txt", ios::out); if (!outFile.is_open()) { printf("导出grade.txt文件失败!\n"); return; } - int size; + size_t size; vector* vg; vg = getAllGrade(connection); if (vg == NULL) { @@ -612,8 +627,9 @@ void exportGradeData(_ConnectionPtr connection) { } outFile << "学号\t课程号\t成绩\n"; size = vg->size(); - for (int i = 0; i < size; i++) { - outFile << (*vg)[i].toString() << "\n"; + for (size_t i = 0; i < size; i++) { + outFile << (*vg)[i].toString(); + if (i != (size - 1)) outFile << "\n"; } printf("成功导出grade.txt文件!\n"); outFile.close(); @@ -630,6 +646,10 @@ void exportAllData(_ConnectionPtr connection) { void importData(_ConnectionPtr connection) { while (true) { try { + // 文件夹不存在则创建文件夹 + if (_access("./data", 0) == -1) { + _mkdir("./data"); + } system("cls"); printf("1.导入学生信息\n"); printf("2.导入课程信息\n"); @@ -669,13 +689,13 @@ void importData(_ConnectionPtr connection) { } void importStudentData(_ConnectionPtr connection) { - ifstream inFile("student.txt", ios::in); + ifstream inFile("./data/student.txt", ios::in); if (!inFile.is_open()) { printf("读取student.txt文件失败!\n"); return; } - string title[5]; + string title[5];//用于存储表头及每行的数据 inFile >> title[0] >> title[1] >> title[2] >> title[3] >> title[4]; if (!(title[0] == "学号" && title[1] == "姓名" && title[2] == "性别" && title[3] == "班级" && title[4] == "状态")) { printf("文件格式异常,读取失败!\n"); @@ -697,13 +717,13 @@ void importStudentData(_ConnectionPtr connection) { } void importCourseData(_ConnectionPtr connection) { - ifstream inFile("course.txt", ios::in); + ifstream inFile("./data/course.txt", ios::in); if (!inFile.is_open()) { printf("读取course.txt文件失败!\n"); return; } - string title[2]; + string title[2];//用于存储表头及每行的数据 inFile >> title[0] >> title[1]; if (!(title[0] == "课程号" && title[1] == "课程名")) { printf("文件格式异常,读取失败!\n"); @@ -722,13 +742,13 @@ void importCourseData(_ConnectionPtr connection) { } void importGradeData(_ConnectionPtr connection) { - ifstream inFile("grade.txt", ios::in); + ifstream inFile("./data/grade.txt", ios::in); if (!inFile.is_open()) { printf("读取grade.txt文件失败!\n"); return; } - string title[3]; + string title[3];//用于存储表头及每行的数据 inFile >> title[0] >> title[1] >> title[2]; if (!(title[0] == "学号" && title[1] == "课程号" && title[2] == "成绩")) { printf("文件格式异常,读取失败!\n"); diff --git a/Menu.h b/Menu.h index 52cc3a2..94442ca 100644 --- a/Menu.h +++ b/Menu.h @@ -1,3 +1,6 @@ +/* +* 菜单接口 +*/ #ifndef MENU_H #define MENU_H @@ -6,37 +9,132 @@ #include #include #include +#include +#include + #include"Student.cpp" #include"Course.cpp" #include"Grade.cpp" #include"DBCUtils.h" #include"MenuUtils.h" +#include"StringUtils.h" #include"StudentDAO.h" #include"GradeDAO.h" #include"CourseDAO.h" using namespace std; +/* +* 主菜单 +* @param connection 数据库连接 +*/ void mainMenu(_ConnectionPtr connection); + +/* +* 菜单-学生成绩管理 +* @param connection 数据库连接 +*/ void studentGradeMenu(_ConnectionPtr connection); + +/* +* 菜单-学生成绩管理-二级拓展菜单 +* @param connection 数据库连接 +*/ void studentGradeExternMenu(_ConnectionPtr connection); + +/* +* 菜单-课程管理 +* @param connection 数据库连接 +*/ void courseMenu(_ConnectionPtr connection); + +/* +* 高级功能(执行用户输入的任意SQL语句) +* @param connection 数据库连接 +*/ void advancedFunction(_ConnectionPtr connection); +/* +* 显示所有学生 +* @param connection 数据库连接 +*/ void showAllStudent(_ConnectionPtr connection); + +/* +* 增加学生 +* @param connection 数据库连接 +*/ void insertStudent(_ConnectionPtr connection); + +/* +* 删除学生 +* @param connection 数据库连接 +*/ void deleteStudent(_ConnectionPtr connection); + +/* +* 修改学生 +* @param connection 数据库连接 +*/ void changeStudent(_ConnectionPtr connection); +/* +* 菜单-导出数据 +* @param connection 数据库连接 +*/ void exportData(_ConnectionPtr connection); + +/* +* 导出学生数据 +* @param connection 数据库连接 +*/ void exportStudentData(_ConnectionPtr connection); + +/* +* 导出课程数据 +* @param connection 数据库连接 +*/ void exportCourseData(_ConnectionPtr connection); + +/* +* 导出成绩数据 +* @param connection 数据库连接 +*/ void exportGradeData(_ConnectionPtr connection); + +/* +* 导出所有数据 +* @param connection 数据库连接 +*/ void exportAllData(_ConnectionPtr connection); +/* +* 菜单-导入数据 +* @param connection 数据库连接 +*/ void importData(_ConnectionPtr connection); + +/* +* 导入学生数据 +* @param connection 数据库连接 +*/ void importStudentData(_ConnectionPtr connection); + +/* +* 导入课程数据 +* @param connection 数据库连接 +*/ void importCourseData(_ConnectionPtr connection); + +/* +* 导入成绩数据 +* @param connection 数据库连接 +*/ void importGradeData(_ConnectionPtr connection); + +/* +* 导入所有数据 +* @param connection 数据库连接 +*/ void importAllData(_ConnectionPtr connection); #endif // !MENU_H \ No newline at end of file diff --git a/MenuUtils.cpp b/MenuUtils.cpp index f81be97..2f4d074 100644 --- a/MenuUtils.cpp +++ b/MenuUtils.cpp @@ -7,23 +7,4 @@ void checkOptInput(int& opt, int low, int high) { cin.clear(); while (cin.get() != '\n'); } -} - -string doubleToString(double num) { - char* buf; - int dec, sign; - - buf = _fcvt(num, 2, &dec, &sign); - - string str; - if (sign) str += "-"; - int i; - for (i = 0; i < dec; i++) { - str += buf[i]; - } - str += "."; - for (; i < strlen(buf); i++) { - str += buf[i]; - } - return str; } \ No newline at end of file diff --git a/MenuUtils.h b/MenuUtils.h index 435f756..320cd41 100644 --- a/MenuUtils.h +++ b/MenuUtils.h @@ -1,12 +1,19 @@ +/* +* 菜单工具接口 +*/ #ifndef MENU_UTILS_H #define MENU_UTILS_H -#define _CRT_SECURE_NO_WARNINGS #include #include using namespace std; +/* +* 检查输入选项 opt∈[low,high](opt∈Z) +* @param opt 输入的选项 +* @param low 选项下限 +* @param high 选项上限 +*/ void checkOptInput(int& opt, int low, int high); -string doubleToString(double num); #endif // !MENU_UTILS_H diff --git a/SAS.vcxproj b/SAS.vcxproj index 1da7adf..a291431 100644 --- a/SAS.vcxproj +++ b/SAS.vcxproj @@ -135,9 +135,9 @@ + - @@ -145,6 +145,7 @@ + diff --git a/SAS.vcxproj.filters b/SAS.vcxproj.filters index 069ba5d..ae1039f 100644 --- a/SAS.vcxproj.filters +++ b/SAS.vcxproj.filters @@ -39,15 +39,15 @@ 婧愭枃浠 - - 婧愭枃浠 - 婧愭枃浠 婧愭枃浠 + + 婧愭枃浠 + @@ -68,5 +68,8 @@ 澶存枃浠 + + 澶存枃浠 + \ No newline at end of file diff --git a/StringUtils.cpp b/StringUtils.cpp new file mode 100644 index 0000000..9a764b5 --- /dev/null +++ b/StringUtils.cpp @@ -0,0 +1,56 @@ +#include"StringUtils.h" + +string doubleToString(double num) { + char* buf;//double数据转换为无符号整数字符串 如12.34 -> 1234 + int dec, sign;//dec->小数点前有几位数字 sign->0为正数,1为负数 + + buf = _fcvt(num, 2, &dec, &sign); + + string str; + if (sign) str += "-"; + int i; + for (i = 0; i < dec; i++) { + str += buf[i]; + } + if (dec == 0) + str += "0"; + if (strcmp(buf, "00") != 0) { + str += "."; + for (; i < strlen(buf); i++) { + str += buf[i]; + } + } + return str; +} + +std::string trim(const std::string& str) { + const std::string& whitespace = " \t"; + const auto strBegin = str.find_first_not_of(whitespace); + if (strBegin == std::string::npos) + return ""; // no content + + const auto strEnd = str.find_last_not_of(whitespace); + const auto strRange = strEnd - strBegin + 1; + + return str.substr(strBegin, strRange); +} + +std::string reduce(const std::string& str) { + const std::string& fill = " "; + const std::string& whitespace = " \t"; + // trim first + auto result = trim(str); + // replace sub ranges + auto beginSpace = result.find_first_of(whitespace); + while (beginSpace != std::string::npos) + { + const auto endSpace = result.find_first_not_of(whitespace, beginSpace); + const auto range = endSpace - beginSpace; + + result.replace(beginSpace, range, fill); + + const auto newStart = beginSpace + fill.length(); + beginSpace = result.find_first_of(whitespace, newStart); + } + return result; +} \ No newline at end of file diff --git a/StringUtils.h b/StringUtils.h new file mode 100644 index 0000000..d090c7f --- /dev/null +++ b/StringUtils.h @@ -0,0 +1,29 @@ +#ifndef STRING_UTILS_H +#define STRING_UTILS_H +#define _CRT_SECURE_NO_WARNINGS + +#include +using std::string; + +/* +* 将double型数据转换为字符串并返回 +* @param num 待转换的double型数据 +* @return string 转换后的字符串 +*/ +string doubleToString(double num); + +/* +* 去除字符串首尾空格 +* @param str 待去除空格的字符串 +* @return string 去除空格后的字符串 +*/ +std::string trim(const std::string& str); + +/* +* 去除字符串首尾空格及中间多余空格 +* @param str 待去除空格的字符串 +* @return string 去除空格后的字符串 +*/ +std::string reduce(const std::string& str); + +#endif // !STRING_UTILS_H diff --git a/Student.cpp b/Student.cpp index 0809648..bc9d0de 100644 --- a/Student.cpp +++ b/Student.cpp @@ -1,3 +1,6 @@ +/* +* 学生表DAO +*/ #ifndef STUDENT_CPP #define STUDENT_CPP diff --git a/StudentDAO.h b/StudentDAO.h index 40728ac..7a884a6 100644 --- a/StudentDAO.h +++ b/StudentDAO.h @@ -1,3 +1,6 @@ +/* +* 学生表数据库操作接口 +*/ #ifndef STUDENT_DAO_H #define STUDENT_DAO_H @@ -7,12 +10,57 @@ #include #include"Student.cpp" +/* +* 向数据库添加学生 +* @param connection 数据库连接 +* @param student 待添加的学生对象 +*/ void addStudent(_ConnectionPtr connection, Student student); + +/* +* 删除学生 +* @param connection 数据库连接 +* @param id 学号 +*/ void deleteStudent(_ConnectionPtr connection, string id); + +/* +* 修改学生班级 +* @param connection 数据库连接 +* @param id 学号 +* @param stuClass 新班级 +*/ void updateStudentClass(_ConnectionPtr connection, string id, string stuClass); + +/* +* 修改学生状态 +* @param connection 数据库连接 +* @param id 学号 +* @param status 学生状态(在读、休学、退学) +*/ void updateStudentStatus(_ConnectionPtr connection, string id, string status); + +/* +* 根据学号获取学生对象 +* @param connection 数据库连接 +* @param id 学号 +* @return Student* student对象指针 +*/ Student* getStudentById(_ConnectionPtr connection, string id); + +/* +* 根据姓名获取学生对象 +* @param connection 数据库连接 +* @param name 姓名 +* @return vector* 以Student对象为元素的vector数组指针 +*/ std::vector* getStudentByName(_ConnectionPtr connection, string name); + +/* +* 获取所有学生 +* @param connection 数据库连接 +* @return vector* 以Student对象为元素的vector数组指针 +*/ std::vector* getAllStudent(_ConnectionPtr connection); #endif // !STUDENT_DAO_H \ No newline at end of file diff --git a/StudentDAOImpl.cpp b/StudentDAOImpl.cpp index de7c5d3..4a43831 100644 --- a/StudentDAOImpl.cpp +++ b/StudentDAOImpl.cpp @@ -31,7 +31,7 @@ void updateStudentStatus(_ConnectionPtr connection, string id, string status) { Student* getStudentById(_ConnectionPtr connection, string id) { string sql = "select * from student where id = '" + id + "'"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 Student *student = new Student(); student->setId((char*)(_bstr_t)record->Fields->GetItem("id")->Value); @@ -45,7 +45,7 @@ Student* getStudentById(_ConnectionPtr connection, string id) { std::vector* getStudentByName(_ConnectionPtr connection, string name) { string sql = "select * from student where name = '" + name + "'"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 std::vector *v = new std::vector(); Student* student; @@ -64,7 +64,7 @@ std::vector* getStudentByName(_ConnectionPtr connection, string name) { std::vector* getAllStudent(_ConnectionPtr connection) { string sql = "select * from student"; _RecordsetPtr record = connection->Execute(sql.c_str(), NULL, (long)0); - if (record->BOF == -1) return NULL; + if (record->BOF == -1) return NULL;//记录集为空 std::vector* v = new std::vector(); Student* student; diff --git a/Test.cpp b/Test.cpp deleted file mode 100644 index 755a36b..0000000 --- a/Test.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* -用于测试DAO功能是否能正常运行 -*/ -#if 0 -#import "c:\\Program Files\\Common Files\\System\\ado\\msado15.dll" no_namespace rename("EOF", "EndOfFile") - -#include // wprintf -#include -#include // setlocale -#include -#include -#include "DBCUtils.h" -#include "StudentDAO.h" -#include "CourseDAO.h" -#include "GradeDAO.h" -using namespace std; - -int main() { - setlocale(LC_ALL, "chs"); - CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - - _ConnectionPtr pconnect(_uuidof(Connection)); - string strConnect = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=stuAdminSystem;Data Source=LAPTOP-4DMOD6O5"; - pconnect->Open(strConnect.c_str(), "", "", NULL); - - //student - /* - Student* stu = new Student("2", "李四", "女", "计科00000", "休学"); - addStudent(pconnect, *stu); - deleteStudent(pconnect, "4"); - updateStudentClass(pconnect, "3", "软件12004"); - updateStudentStatus(pconnect, "3", "休学"); - - Student student = getStudentById(pconnect, "1"); - cout << student.toString() << "\n"; - - vector v = getStudentByName(pconnect, "张三"); - for (int i = 0; i < v.size(); i++) - cout << v[i].toString() << "\n"; - */ - - //course - /* - Course* course1 = new Course("A001","高数"); - Course* course2 = new Course("A002","C语言"); - Course* course3 = new Course("A003","体育"); - addCourse(pconnect, *course1); - addCourse(pconnect, *course2); - addCourse(pconnect, *course3); - - deleteCourse(pconnect, "A002"); - updateCourseName(pconnect, "A003", "物理"); - - Course cou = getCourseById(pconnect, "A001"); - cout << cou.toString() << "\n"; - - vector v = getCourseByName(pconnect, "高数"); - for (int i = 0; i < v.size(); i++) - cout << v[i].toString() << "\n"; - */ - - //grade - /* - Grade* course1 = new Grade("1","A001","95"); - Grade* course2 = new Grade("1","A001-1", "95"); - Grade* course3 = new Grade("1","A003", "95"); - Grade* course4 = new Grade("2","A001", "95"); - Grade* course5 = new Grade("2","A003", "95"); - addGrade(pconnect, *course1); - addGrade(pconnect, *course2); - addGrade(pconnect, *course3); - addGrade(pconnect, *course4); - addGrade(pconnect, *course5); - - deleteOnesGrade(pconnect, "1","A001-1"); - deleteGradeByStuId(pconnect, "1"); - deleteGradeByCourseId(pconnect, "A001"); - - - updateOnesGrade(pconnect,"1","A001-1","98.4"); - - Grade gra = getOnesGrade(pconnect, "1","A001"); - cout << gra.toString() << "\n"; - - cout << "\n"; - - vector v = getGradeByStuId(pconnect, "1"); - for (int i = 0; i < v.size(); i++) - cout << v[i].toString() << "\n"; - - cout << "\n"; - - vector v1 = getGradeByCourseId(pconnect, "A001"); - for (int i = 0; i < v1.size(); i++) - cout << v1[i].toString() << "\n"; - */ - CoUninitialize(); - return 0; -} -#endif \ No newline at end of file diff --git a/main.cpp b/main.cpp index 2215f15..a862f05 100644 --- a/main.cpp +++ b/main.cpp @@ -1,12 +1,11 @@ +/* +* 程序入口 +*/ #import "c:\\Program Files\\Common Files\\System\\ado\\msado15.dll" no_namespace rename("EOF", "EndOfFile") #include // wprintf -#include #include // setlocale -#include -#include #include "DBCUtils.h" -#include "StudentDAO.h" #include "Menu.h" using namespace std;