引用头文件
#include <iostream>
#include<fstream>
#include<string>
#include<cstring>
#define MAXSIZE 100
#define OK 1
#define ERROR0 -3
#define ERROR1 0
#define ERROR2 -1
#define OVERFLOW -2
using namespace std; 结构体类型定义
typedef int status;//返回值状态
typedef int ElemType;//返回值的类型
//学生信息结构体
struct studentInformation {
int id; // 储存每条数据id
char stuName[7]; // 姓名
char stuNum[14]; // 学号
char stuClass[8]; // 班级
float verbal; // 语文成绩
float math; // 数学成绩
};
//顺序表结构体
typedef struct {
studentInformation* elem; // 顺序表首地址
int length; // 表长
} SqlList; 函数声明
/* 初始模块 */
status initListSq(SqlList& L); // 顺序表的初始化
status importData(SqlList &L); // 建立录入成绩函数
status save(SqlList& L); // 保存函数
/* CRUD模块 */
status insertion(SqlList &L, studentInformation stu, int n); // 添加学生信息
status deleteStudent(SqlList &L, studentInformation stu, int n); // 删除学生信息
status modifyStudents(SqlList &L, studentInformation stu, int n); // 修改学生信息
int findStuNum(SqlList L,studentInformation stu); // 按照学号查找学生信息
int findStuName(SqlList L,studentInformation stu); // 按照姓名查找学生信息
/* 补充模块 */
status showAll(SqlList L); // 显示所有学生信息
/*扩展模块*/
void ASort(SqlList L); // 语文排序
void MSort(SqlList L); // 数学排序
void idSort(SqlList L);// id排序
void filterScore(SqlList L,int type);// 筛选
void collectScore(SqlList L,int type);// 汇总
void dY(SqlList L,int type,float score);// 大于
int xY(SqlList L,int type,float score);// 小于
void nDY(SqlList L,int type,float score);// 不大于
int nXY(SqlList L,int type,float score);// 不小于
int between(SqlList L,int type,float score1,float score2);//介于
void frontTen(SqlList L,int type);//前十名
void BehindTen(SqlList L,int type);// 后十名 主函数
主菜单目录
cout << "****************************************" << endl;
cout << "* 1、录入学生成绩 2、添加学生信息 3、删除学生信息 *" << endl;
cout << "* 4、修改学生信息 5、查找学生信息 6、显示所有学生信息 *" << endl;
cout << "* 7、对学生成绩进行排序 8、单科目学生成绩筛选 9、单科目汇总成绩 *" << endl;
cout << "* 0、退出 *" << endl;
cout << "****************************************" << endl;
cout << "请输入操作项【0-9】:"; 1、录入学生成绩
思路:
当用户按1的时候执行switch内的case为1的内容;既然是录入成绩一定有初始化,和文件读取等内容。所以就有了函数 initListSq 顺序表初始化函数、以及 importData 文件读取函数,和为了提高用户体验感的 showAll 显示当前录入读取文件内的所有内容。
代码展示
case 1: { // 录入学生成绩
// 创建顺序表
if (initListSq(L)) {
cout << "顺序表的初始化成功!" << endl;
} else {
cout << "顺序表的初始化失败!" << endl;
}
int res = importData(L);
if (res == 1) {
showAll(L);
cout << "顺序表信息录入成功!" << endl;
} else {
cout << "顺序表信息录入失败!" << endl;
}
break;
} initListSq 函数
思路
使用数组储存方式先默认申请100个空间、 MAXSIZE 在引用文件解释过。如果没有首地址达标申请失败则直接退出,否则给将整个表长定义初始为0;
代码展示
// 顺序表的初始化
status initListSq(SqlList& L) {
L.elem = new studentInformation[MAXSIZE]; //申请100个studentInformation数组
if (!L.elem) {
// 内存申请失败,直接退出程序
exit(OVERFLOW);
}
L.length = 0; // 初始
return OK;
}; importData 函数
思路
引用指针 FILE *fp; fopen打开文件函数,写入文件路径和 r 读取文件,如果等于空代表读取失败。否则 fscanf 函数进行读出储存下来,并且不断扩容表长 length。
代码展示
// 建立录入成绩函数
status importData(SqlList &L) {
FILE *fp;
int i = L.length;
if((fp = fopen("D:\\C++\\gradeManagementSystem\\stu.txt","r")) == NULL){
printf("读取失败!");
return ERROR1;
}
while(!feof(fp)){
fscanf(fp,"%d%s%s%s%f%f",&L.elem[i].id,L.elem[i].stuName,L.elem[i].stuNum,
L.elem[i].stuClass,&L.elem[i].verbal,&L.elem[i].math);
i++;
L.length++;
}
fclose(fp);
return OK;
}; 2、添加学生信息
思路
当用户按2的时候执行switch内的case为2的内容;既然是添加学生信息一定要问用户是按照学生学号添加还是学生姓名添加,所以提示用户输入二级菜单,用户输入1则是按照学号添加,输入2则是按照姓名添加。除了这两个数之外都可以判定为输入的数字不合法,最后重新操作。也用到了添加学生信息函数 insertion。
代码展示
case 2: { // 添加学生信息
cout << "****************************************" << endl;
cout << "* 1、按学生学号添加 2、按学生姓名添加 *" << endl;
cout << "****************************************" << endl;
cout << "请输入操作项【1-2】:";
cin >> a;
if (a == 1){
cout << "请输入要添加的学生学号: ";
cin >> e.stuNum;
insertion(L, e, a);
}else if(a == 2){
cout << "请输入要添加的学生姓名: ";
cin >> e.stuName;
insertion(L, e, a);
}else if(a != 1 || a != 2){
cout << "您输入的内容不合法!";
}
break;
} insertion 函数
思路
当用户输入1为根据姓名添加,输入2为根据学号添加。分别根据用户输入的姓名或学号使用 findStuName 或 findStuNum 查询函数来查看库内是否有相同的数据,如果有则提示用户已存在,否则提示用户输入下一步姓名或学号进行再次查看用户输入的姓名或学号是否存在,有则提示已存在,否则进行继续输入班级、语文成绩和数学成绩的添加,最终添加成功,提示用户新增成功!等内容。findStuName和 findStuNum 函数后序会详细解释。
代码展示
// 添加学生信息
status insertion(SqlList &L, studentInformation stu, int n){
if (n == 2){
int res1 = findStuName(L,stu);
if(res1 == -1) {
cout << "请输入要添加的学生学号:";
cin >> stu.stuNum;
int result = findStuNum(L,stu);
if (result == -1){
++L.length;
L.elem[L.length-2].id = L.elem[L.length-3].id + 1;
strcpy(L.elem[L.length-2].stuNum, stu.stuNum);
// strcpy用错将字符串stu.stuName 赋值给 L.elem[L.length-2].stuName 数组。
strcpy(L.elem[L.length-2].stuName, stu.stuName);
cout << "请输入要添加的学生班级:";
cin >> L.elem[L.length-2].stuClass;
cout << "请输入要添加学生的语文成绩:";
cin >> L.elem[L.length-2].verbal;
cout << "请输入要添加学生的数学成绩:";
cin >> L.elem[L.length-2].math;
cout << "新增成功!" << endl;
findStuNum(L,stu);
}else if(result == 1){
cout << "您输入的学生学号已存在";
}
}else if(res1 == 1) {
cout << "您输入的学生姓名已存在!" << endl;
}
}else if (n == 1){
int res2 = findStuNum(L,stu);
if(res2 == -1){
cout << "请输入要添加的学生姓名:";
cin >> stu.stuName;
int result = findStuName(L,stu);
if (result == -1){
++L.length;
L.elem[L.length-2].id = L.elem[L.length-3].id + 1;
strcpy(L.elem[L.length-2].stuNum, stu.stuNum);
strcpy(L.elem[L.length-2].stuName, stu.stuName);
cout << "请输入要添加的学生班级:";
cin >> L.elem[L.length-2].stuClass;
cout << "请输入要添加学生的语文成绩:";
cin >> L.elem[L.length-2].verbal;
cout << "请输入要添加学生的数学成绩:";
cin >> L.elem[L.length-2].math;
cout << "新增成功!" << endl;
findStuName(L,stu);
}else{
cout << "您输入的学生姓名已存在!";
}
}else if(res2 == 1) {
cout << "您输入的学生学号已存在!" << endl;
}
}
return OK;
} 3、删除学生信息
思路
当用户按3的时候执行switch内的case为3的内容;既然是删除学生信息一定要问用户是按照学生学号删除还是学生姓名删除,所以提示用户输入二级菜单,用户输入1则是按照学号删除,输入2则是按照姓名删除。除了这两个数之外都可以判定为输入的数字不合法,最后重新操作。也用到了删除学生信息函数 deleteStudent。
代码展示
case 3: { // 删除学生信息
cout << "****************************************" << endl;
cout << "* 1、按学生学号删除 2、按学生姓名删除 *" << endl;
cout << "****************************************" << endl;
cout << "请输入操作项【1-2】:";
cin >> a;
if (a == 1){
cout << "请输入要删除的学生学号: ";
cin >> e.stuNum;
deleteStudent(L, e, a);
}else if(a == 2){
cout << "请输入要删除的学生姓名: ";
cin >> e.stuName;
deleteStudent(L, e, a);
}else{
cout << "您输入的内容不合法!";
}
break;
} deleteStudent 函数
思路
传入参数L结构体对象地址,并且传入用户输入的对象以及二级菜单选项。根据用户输 入的菜单选项进行判断用户输入的是姓名还是学号进行删除操作。找到要删除的地址下 标,让第二个表内容进行顶替。
代码展示
// 删除学生信息
status deleteStudent(SqlList &L, studentInformation stu, int n){
if (n == 2){
int res1 = findStuName(L,stu);
if(res1 == -1) {
cout << "您输入的学生姓名未存在!" << endl;
}else if(res1 == 1) {
int index = 0;
for(int i = 0; i < L.length;i++){
if(strcmp(L.elem[i].stuName,stu.stuName)==0){
index = i; // 索引下标获取成功
}
}
for(int i = index+1; i < L.length;i++){
L.elem[i-1] = L.elem[i];
}
L.length --;
cout << "删除成功!" << endl;
}
}else if (n == 1){
int res2 = findStuNum(L,stu);
if(res2 == -1){
cout << "您输入的学生学号未存在!" << endl;
}else if(res2 == 1) {
int index = 0;
for(int i = 0; i < L.length;i++){
if(strcmp(L.elem[i].stuNum,stu.stuNum)==0){
index = i; // 索引下标获取成功
}
}
for(int i = index+1; i < L.length;i++){
L.elem[i-1] = L.elem[i];
}
L.length --;
cout << "删除成功!" << endl;
}
}
return OK;
} 4、修改学生信息
思路
当用户按4的时候执行switch内的case为4的内容;既然是修改学生信息一定要问用户是按照学生学号修改还是学生姓名修改,所以提示用户输入二级菜单,用户输入1则是按照学号修改,输入2则是按照姓名修改。除了这两个数之外都可以判定为输入的数字不合法,最后重新操作。也用到了修改学生信息函数 modifyStudents。
代码展示
case 4: { // 修改学生信息
cout << "****************************************" << endl;
cout << "* 1、按学生学号修改 2、按学生姓名修改 *" << endl;
cout << "****************************************" << endl;
cout << "请输入操作项【1-2】:";
cin >> a;
if (a == 1){
cout << "请输入要修改的学生学号: ";
cin >> e.stuNum;
modifyStudents(L, e, a);
}else if(a == 2){
cout << "请输入要修改的学生姓名: ";
cin >> e.stuName;
modifyStudents(L, e, a);
}else{
cout << "您输入的内容不合法!";
}
break;
} modifyStudents 函数
思路
按照用户输入的姓名或者学号进行查找数据,找不到进行提示您输入的用户不存在,找 到返回数据,对语文和数学成绩进行更新操作。
代码展示
// 修改学生信息
status modifyStudents(SqlList &L, studentInformation stu, int n){
if (n == 2){
int res1 = findStuName(L,stu);
if(res1 == -1) {
cout << "您输入的学生姓名未存在!" << endl;
}else if(res1 == 1) {
int index = 0;
for(int i = 0; i < L.length;i++){
if(strcmp(L.elem[i].stuName,stu.stuName)==0){
index = i; // 索引下标获取成功
}
}
cout << "请输入要修改的学生语文成绩";
cin >> L.elem[index].verbal;
cout << "请输入要修改的学生数学成绩";
cin >> L.elem[index].math;
cout << "修改成功!" << endl;
findStuName(L,stu);
}
}else if (n == 1){
int res2 = findStuNum(L,stu);
if(res2 == -1){
cout << "您输入的学生学号未存在!" << endl;
}else if(res2 == 1) {
int index = 0;
for(int i = 0; i < L.length;i++){
if(strcmp(L.elem[i].stuNum,stu.stuNum)==0){
index = i; // 索引下标获取成功
}
}
cout << "请输入要修改的学生语文成绩";
cin >> L.elem[index].verbal;
cout << "请输入要修改的学生数学成绩";
cin >> L.elem[index].math;
cout << "修改成功!" << endl;
findStuNum(L,stu);
}
}
return OK;
}
5、查找学生
思路
当用户按5的时候执行switch内的case为4的内容;既然是查找学生信息一定要问用户是按照学生学号查找还是学生姓名查找,所以提示用户输入二级菜单,用户输入1则是按照学号查找,输入2则是按照姓名查找。除了这两个数之外都可以判定为输入的数字不合法,最后重新操作。也用到了查找学生信息函数分别是,按姓名查找 findStuName 按学号查找函数 findStuNum。
代码展示
case 5: { // 查找学生
cout << "****************************************" << endl;
cout << "* 1、按学生学号查找 2、按学生姓名查找 *" << endl;
cout << "****************************************" << endl;
cout << "请输入操作项【1-2】:";
cin >> a;
if (a == 1){
cout << "请输入要查找的学生学号: ";
cin >> e.stuNum;
int res = findStuNum(L, e);
if (res == -1){
cout << "查找的学号不存在!" << endl;
}else{
cout << "查找成功!" << endl;
}
}else if(a == 2){
cout << "请输入要查找的学生姓名: ";
cin >> e.stuName;
int res = findStuName(L, e);
if (res == -1){
cout << "查找的学生姓名不存在!" << endl;
}else{
cout << "查找成功!" << endl;
}
}else if(a != 1 || a != 2){
cout << "您输入的内容不合法";
}
break;
} findStuName 函数
思路
从首元表进行遍历比较如果相等进行返回当前姓名下的所有学生信息。
代码展示
// 按照姓名查找学生信息
int findStuName(SqlList L,studentInformation stu){ // 查找
int i;
for(i=0; i < L.length;i++){
if(strcmp(L.elem[i].stuName,stu.stuName)==0){ //strcmp(char*/char [])
printf("\n");
printf("%s\t%s\t%s\t%s\t%s\n","姓名","学号"," 班级"," 语文"," 数学");
printf("%s\t%s\t%s\t%.2f\t%.2f\n",L.elem[i].stuName,
L.elem[i].stuNum, L.elem[i].stuClass,
L.elem[i].verbal, L.elem[i].math);
return 1; // 查找成功
}
}
return -1; //查找失败
} findStuNum 函数
思路
从首元表进行遍历比较如果相等进行返回当前学号下的所有学生信息。
代码展示
// 按照学号查找学生信息
int findStuNum(SqlList L,studentInformation stu){ // 查找
int i;
for(i=0; i < L.length;i++){
if(strcmp(L.elem[i].stuNum,stu.stuNum)==0){ //strcmp(char*/char [])
printf("\n");
printf("%s\t%s\t%s\t%s\t%s\n","姓名","学号"," 班级"," 语文"," 数学");
printf("%s\t%s\t%s\t%.2f\t%.2f\n",L.elem[i].stuName,
L.elem[i].stuNum, L.elem[i].stuClass,
L.elem[i].verbal, L.elem[i].math);
return 1; // 查找成功
}
}
return -1; //查找失败
}
6、显示所有学生信息
思路
当用户按6的时执行switch内的case为6的内容;既然是显示所有用户信息,那就比较简单了从开始首元表遍历到最后一个,按照格式进行罗列出来。
代码展示
case 6: { // 显示所有学生信息
showAll(L);
break;
} showAll 函数
思路
使用 for 循环语法从表的开始0,遍历到最后一个表 length-1 结束。把所有信息按照规范打印出来。
代码展示
// 显示所有学生信息
status showAll(SqlList L){
int i;
printf("\n");
printf("%s\t%s\t%s\t%s\t%s\n","姓名","学号"," 班级"," 语文"," 数学");
for(i=0; i < L.length-1;i++){
printf("%s\t%s\t%s\t%.2f\t%.2f\n",L.elem[i].stuName, L.elem[i].stuNum, L.elem[i].stuClass,
L.elem[i].verbal, L.elem[i].math);
}
return OK;
}
7、对学生成绩进行排序
思路
当用户按7的时候执行switch内的case为7的内容;既然是对所有科目中的一科进行遍历,我们采用所有都是升序遍历,但是有每一科目所有分了一个二级菜单,让用户可以选择对哪一科目进行排序,我们模拟出语文和数学两个科目。当用户如1时对语文排序后展示给用户或者输入2时数学排序后展示给用户。最后在将原来的顺序按照id排序还原。
代码展示
case 7: { // 对学生成绩进行排序
cout << "****************************************" << endl;
cout << "* 1、按语文科目排序 2、按数学科目排序 *" << endl;
cout << "****************************************" << endl;
cout << "请输入操作项【1-2】:";
cin >> a;
if(a == 1){
ASort(L);
showAll(L);
idSort(L); //恢复
}else{
MSort(L);
showAll(L);
idSort(L); //恢复
}
break;
} ASort 函数
思路
采用选择排序,外循环与内循环进行比较,找到整个表中语文成绩最小的放在下标为首 地址的位置上,找第二小的放在下标第二个位置上依次比较排放直到结束。
代码展示
// 语文排序
void ASort(SqlList L){
int i,j;
for(i = 0; i < L.length - 2; i++){
for(j = i + 1; j < L.length-1; j++){
if(L.elem[i].verbal > L.elem[j].verbal){
//中间替换变量
float tmp1 = L.elem[i].verbal;
float tmp2 = L.elem[i].math;
int idNum = L.elem[i].id;
char stuName[7];
char stuNum[14];
char stuClass[8];
//交换:将stuName暂时存放L.elem[i]中的数据
strcpy(stuName,L.elem[i].stuName);
strcpy(stuNum,L.elem[i].stuNum);
strcpy(stuClass,L.elem[i].stuClass);
L.elem[i].id = L.elem[j].id;
L.elem[j].id = idNum;
L.elem[i].verbal = L.elem[j].verbal;
L.elem[j].verbal = tmp1;
L.elem[i].math = L.elem[j].math;
L.elem[j].math = tmp2;
//交换:将L.elem[j]中的数据复制到 L.elem[i]中
strcpy(L.elem[i].stuName,L.elem[j].stuName);
strcpy(L.elem[i].stuNum,L.elem[j].stuNum);
strcpy(L.elem[i].stuClass,L.elem[j].stuClass);
//交换:将stuName中数据存放L.elem[j]中的数据
strcpy(L.elem[j].stuName,stuName);
strcpy(L.elem[j].stuNum,stuNum);
strcpy(L.elem[j].stuClass,stuClass);
}
}
}
} MSort 函数
思路
采用选择排序,外循环与内循环进行比较,找到整个表中数学成绩最小的放在下标为首 地址的位置上,找第二小的放在下标第二个位置上依次比较排放直到结束。
代码展示
// 数学排序
void MSort(SqlList L){
int i,j;
for(i = 0; i < L.length - 2; i++){
for(j = i + 1; j < L.length-1; j++){
if(L.elem[i].math > L.elem[j].math){
//中间替换变量
float tmp1 = L.elem[i].math;
float tmp2 =L.elem[i].verbal;
int idNum = L.elem[i].id;
char stuName[7];
char stuNum[14];
char stuClass[8];
//交换:将stuName暂时存放L.elem[i]中的数据
strcpy(stuName,L.elem[i].stuName);
strcpy(stuNum,L.elem[i].stuNum);
strcpy(stuClass,L.elem[i].stuClass);
L.elem[i].id = L.elem[j].id;
L.elem[j].id = idNum;
L.elem[i].math = L.elem[j].math;
L.elem[j].math = tmp1;
L.elem[i].verbal = L.elem[j].verbal;
L.elem[j].verbal = tmp2;
//交换:将L.elem[j]中的数据复制到 L.elem[i]中
strcpy(L.elem[i].stuName,L.elem[j].stuName);
strcpy(L.elem[i].stuNum,L.elem[j].stuNum);
strcpy(L.elem[i].stuClass,L.elem[j].stuClass);
//交换:将stuName中数据存放L.elem[j]中的数据
strcpy(L.elem[j].stuName,stuName);
strcpy(L.elem[j].stuNum,stuNum);
strcpy(L.elem[j].stuClass,stuClass);
}
}
}
} idSort 函数
思路
为了让源文件的顺序不变,所以创建了ID字段,为了方便还原,当然ID排序选择的也 是选择排序方式进行排序,外循环与内循环进行比较,找到整个表中ID最小的放在下 标为首地址的位置上,找第二小的放在下标第二个位置上依次比较排放直到结束。
代码展示
//id排序
void idSort(SqlList L){
int i,j;
for(i = 0; i < L.length - 2; i++){
for(j = i + 1; j < L.length-1; j++){
if(L.elem[i].id > L.elem[j].id){
//中间替换变量
float tmp1 = L.elem[i].verbal;
float tmp2 = L.elem[i].math;
int tmp = L.elem[i].id;
char stuName[7];
char stuNum[14];
char stuClass[8];
//交换:将stuName暂时存放L.elem[i]中的数据
strcpy(stuName,L.elem[i].stuName);
strcpy(stuNum,L.elem[i].stuNum);
strcpy(stuClass,L.elem[i].stuClass);
L.elem[i].id = L.elem[j].id;
L.elem[j].id = tmp;
L.elem[i].verbal = L.elem[j].verbal;
L.elem[j].verbal = tmp1;
L.elem[i].math = L.elem[j].math;
L.elem[j].math = tmp2;
//交换:将L.elem[j]中的数据复制到 L.elem[i]中
strcpy(L.elem[i].stuName,L.elem[j].stuName);
strcpy(L.elem[i].stuNum,L.elem[j].stuNum);
strcpy(L.elem[i].stuClass,L.elem[j].stuClass);
//交换:将stuName中数据存放L.elem[j]中的数据
strcpy(L.elem[j].stuName,stuName);
strcpy(L.elem[j].stuNum,stuNum);
strcpy(L.elem[j].stuClass,stuClass);
}
}
}
} 8、单科目学生成绩筛选
思路
当用户按8的时候执行switch内的case为8的内容;既然是单科目成绩进行筛选时,一定是某一科,所以有二级菜单对某一科目进行筛选,但是因为用户筛选的方式可能不同我们增加了三级菜单。
代码展示
case 8: { // 单科目学生成绩筛选
cout << "****************************************" << endl;
cout << "* 1、按语文科目筛选 2、按数学科目筛选 *" << endl;
cout << "****************************************" << endl;
cout << "请输入操作项【1-2】:";
cin >> a;
if(a == 1){ // 语文
filterScore(L, a);
idSort(L); //恢复
} else if(a == 2) { //数学
filterScore(L,a);
idSort(L); //恢复
}
break;
} filterScore 函数
思路
保存用户输入的二级菜单选项可以知道用户选择语文还是数学科目进行的筛选。然后进 行排序的基础上对数进行获取,这样可以获取用户想要的数据,在排序的基础上进行筛 选也是为了提高运行效率。假设说用户想要前十个数据,那我们排好序的数据表内只用 那后十个数据就行了。
代码展示
// 筛选
void filterScore(SqlList L,int type){
if(type == 1){ //语文
printf("-----------[1].大于x\n");
printf("-----------[2].小于x\n");
printf("-----------[3].不大于x\n");
printf("-----------[4].不小于x\n");
printf("-----------[5].介于x和y之间\n");
printf("-----------[6].前十名\n");
printf("-----------[7].后十名\n");
int sec;
cout << "请输入操作项【1-7】:";
scanf("%d",&sec);
switch(sec){
case 1:
printf("请输入相应的成绩\n");
float score1;
scanf("%f",&score1);
//大于函数
dY(L,type,score1);
break;
case 2:
printf("请输入成绩score:");
float score2;
scanf("%f",&score2);
//小于函数
xY(L,type,score2);
break;
case 3:
printf("请输入成绩score:");
float score3;
scanf("%f",&score3);
//不大于函数
nDY(L,type, score3);
break;
case 4:
printf("请输入成绩score:");
float score4;
scanf("%f",&score4);
//不小于函数
nXY(L,type,score4);
break;
case 5:
printf("请输入成绩score:");
float score5;
float score0;
scanf("%f",&score5);
scanf("%f",&score0);
//介于函数
between(L,type,score5,score0);
break;
case 6:
//前十名
frontTen(L,type);
break;
case 7:
//后十名
BehindTen(L,type);
break;
}
}else if(type == 2) //数学
printf("-----------[1].大于x\n");
printf("-----------[2].小于x\n");
printf("-----------[3].不大于x\n");
printf("-----------[4].不小于x\n");
printf("-----------[5].介于x和y之间\n");
printf("-----------[6].前十名\n");
printf("-----------[7].后十名\n");
int sec;
cout << "请输入操作项【1-7】:";
scanf("%d",&sec);
switch(sec){
case 1:
printf("请输入相应的成绩:");
float score1;
scanf("%f",&score1);
//大于函数
dY(L,type,score1);
break;
case 2:
printf("请输入成绩score:");
float score2;
scanf("%f",&score2);
//小于函数
xY(L,type,score2);
break;
case 3:
printf("请输入成绩score:");
float score3;
scanf("%f",&score3);
//不大于函数
nDY(L,type,score3);
break;
case 4:
printf("请输入成绩score:");
float score4;
scanf("%f",&score4);
//不小于函数
nXY(L,type,score4);
break;
case 5:
printf("请输入成绩score:");
float score5;
float score0;
scanf("%f",&score5);
scanf("%f",&score0);
//介于函数
between(L,type,score5,score0);
break;
case 6:
//前十名
frontTen(L,type);
break;
case 7:
//后十名
BehindTen(L,type);
break;
}
} dY 函数
思路
将数组先按照输入的某科目进行排序,最后设立是否flag来表示什么时候结束。从结束的前一个指针进行截断打印操作。
代码展示
// 大于
void dY(SqlList L,int type,float score){
if(type == 1){//语文
ASort(L);
int i,j,flag;
for(i = 0; i < L.length-1; i++){
if(L.elem[i].verbal > score)
break;
}
for(j = i; j < L.length-1;j++){
flag = 1;//标志位
printf("%s\t%s\t%s\t%.2f\n",L.elem[j].stuName,L.elem[j].stuNum,L.elem[j].stuClass,L.elem[j].verbal);
}
if(flag != 1){
printf("不存在符合该条件的记录\n");
}
}else if(type == 2){//数学
MSort(L);
int i,j,flag;
for(i = 0; i < L.length-1; i++){
if(L.elem[i].math > score)
break;
}
for(j = i; j < L.length-1;j++){
flag = 1;//标志位
printf("%s\t%s\t%s\t%.2f\n",L.elem[j].stuName,L.elem[j].stuNum,L.elem[j].stuClass,L.elem[j].math);
}
if(flag != 1){
printf("不存在符合该条件的记录\n");
}
}
} xY 函数
思路
将数组先按照输入的某科目进行排序,最后设立是否flag来表示什么时候结束。从结束的前一个指针进行截断打印操作。
代码展示
int xY(SqlList L,int type,float score){
int countA = 0;
int countM = 0;
if(type == 1){//语文
ASort(L);
int i,j,flag;
for(i = 0; i < L.length-1; i++){//找到比当前输入成绩大的数据的索引后退出
if(L.elem[i].verbal > score)
break;
}
for(j = 0; j < i;j++){ //遍历它之前的元素--比它小
flag = 1; //标志位
if(L.elem[j].verbal != score){
countA++;
printf("%s\t%s\t%s\t%.2f\n",L.elem[j].stuName,L.elem[j].stuNum,L.elem[j].stuClass,L.elem[j].verbal);
}
}
if(flag != 1){
printf("不存在符合该条件的记录\n");
}
}else if (type == 2){//数学
MSort(L);
int i,j,flag;
for(i = 0; i < L.length-1; i++){
if(L.elem[i].math > score)
break;
}
for(j = 0; j < i;j++){
flag = 1;
if(L.elem[j].math != score){
countM++;
printf("%s\t%s\t%s\t%.2f\n",L.elem[j].stuName,L.elem[j].stuNum,L.elem[j].stuClass,L.elem[j].math);
}
}
if(flag != 1){
printf("不存在符合该条件的记录\n");
}
}
if(type == 1){
return countA;
}else{
return countM;
}
} 9、单科目汇总成绩
思路
当用户按9的时候执行switch内的case为9的内容;既然是单科目成绩进行汇总时,一定是某一科,所以有二级菜单对某一科目进行汇总,但是因为用户汇总的方式可能不同我们增加了三级菜单。
代码展示
case 9: { // 单科目汇总成绩
cout << "****************************************" << endl;
cout << "* 1、按语文科目汇总 2、按数学科目汇总 *" << endl;
cout << "****************************************" << endl;
cout << "请输入操作项【1-2】:";
cin >> a;
if(a == 1){ // 语文
collectScore(L,a);
idSort(L); //恢复
}else if(a == 2) { //数学
collectScore(L, a);
idSort(L); //恢复
}
break;
} collectScore 函数
思路
按照用户输入的科目进行汇总功能也是在排序的基础上进行汇总会更加方便,如果数据 量过大,效率也可以提现处理更高。
代码展示
// 汇总
void collectScore(SqlList L,int type){
if(type == 1){ //语文
// >= 90
printf("成绩在90以及90分以上者:\n");
int count90 = nXY(L,type,90.00);
if(count90 != 0){
printf("总计:%d人\n",count90);
}else{
printf("无\n");
}
// 80-89
printf("--------------------------------------------------\n");
printf("成绩在80以及89分之间者:\n");
int count80 = between(L,type,80.00,89.00);
if(count80 != 0){
printf("总计:%d人\n",count80);
}else{
printf("无\n");
}
// 70-79
printf("--------------------------------------------------\n");
printf("成绩在70以及79分之间者:\n");
int count70 = between(L,type,70.00,79.00);
if(count70 != 0){
printf("总计:%d人\n",count70);
}else{
printf("无\n");
}
// 60-69
printf("--------------------------------------------------\n");
printf("成绩在60以及69分之间者:\n");
int count69 = between(L,type,60.00,69.00);
if(count69 != 0){
printf("总计:%d人\n",count69);
}else{
printf("无\n");
}
// <60
printf("--------------------------------------------------\n");
printf("成绩不及格者:\n");
int count60 = xY(L,type,60.00);
if(count60 != 0){
printf("总计:%d人\n",count60);
}else{
printf("无\n");
}
}else if(type == 2){//数学
// >= 90
printf("成绩在90以及90分以上者:\n");
int count90 = nXY(L,type,90.00);
if(count90 != 0){
printf("总计:%d人\n",count90);
}else{
printf("无\n");
}
// 80-89
printf("--------------------------------------------------\n");
printf("成绩在80以及89分之间者:\n");
int count80 = between(L,type,80.00,89.00);
if(count80 != 0){
printf("总计:%d人\n",count80);
}else{
printf("无\n");
}
// 70-79
printf("--------------------------------------------------\n");
printf("成绩在70以及79分之间者:\n");
int count70 = between(L,type,70.00,79.00);
if(count70 != 0){
printf("总计:%d人\n",count70);
}else{
printf("无\n");
}
// 60-69
printf("--------------------------------------------------\n");
printf("成绩在60以及69分之间者:\n");
int count69 = between(L,type,60.00,69.00);
if(count69 != 0){
printf("总计:%d人\n",count69);
}else{
printf("无\n");
}
// <60
printf("--------------------------------------------------\n");
printf("成绩不及格者:\n");
int count60 = xY(L,type,60.00);
if(count60 != 0){
printf("总计:%d人\n",count60);
}else{
printf("无\n");
}
}
} 10、退出
思路
当用户输入0时,进行保存退出。
代码展示
case 0: { // 退出
save(L);
exit(0);
break;
} save 函数
思路
保存相当于把之前运存里的数据储存在硬盘内存里的操作,当用户退出前记性,读取运 存数据,依次存在在TXT文件中。
代码展示
// 保存函数
status save(SqlList& L) {
FILE* fp;
int i;
if ((fp = fopen("../stu.txt", "w")) == NULL) {
printf("读取失败\n");
}
else {
for (i = 0; i < L.length-1; i++) {
fprintf(fp, "%d\t%s\t%s\t%s\t%.2f\t%.2f\n", L.elem[i].id,
L.elem[i].stuName, L.elem[i].stuNum, L.elem[i].stuClass,
L.elem[i].verbal, L.elem[i].math);
}
fclose(fp);
}
return OK;
} 想要课程设计实习报告和完整代码就点击下方链接下载吧!
|