要求:
(1) 学生成绩信息保存在文件中
(2) 学生成绩信息查询、删除、修改和显示
(3) 学生成绩总分计算和排名
(4) 学生成绩信息的统计:根据科目统计每个分数段的人,统计结果可以保存文件中。
(5) 利用菜单管理
目录
(2) func.cpp
(3) main.cpp
#ifndef _FUNC_H
#define _FUNC_H
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <malloc.h>
#include <string.h>
#define LEN sizeof(struct Student)
struct Score
{
float gaoshu;
float yingyu;
float yuwen;
};
struct Student
{
char name[20];
int id;
struct Score score;
float sum;
int rank;
struct Student *next;
};
void login();
int menu();
void createList();
void ranksum();
void writeInFile();
void showOriginalInfo();
void showOneStudentInfo(struct Student *p);
void insertInfo();
void queryInfo();
void modifyInfo();
int modifyMenu();
int idOrName();
void showData();
#endif
#include "func.h"
char title[7][20] = { "学号\t", "姓名\t", "高数\t", "语文\t", "英语\t", "总分\t", "排名" };
struct Student *head;
void login()
{
printf("\n\n\t\t\t----------------- 学生信息管理系统 -----------------\n");
printf("\n\n\t\t\t 版本号:v1.0 \n");
printf("\n\n\t\t\t By Zyf \n");
}
int menu()
{
int input;
do
{
system("cls");
printf("\n\n");
printf("\t\t\t _________________________________________________\n");
printf("\t\t\t| |\n");
printf("\t\t\t| *****学生信息管理系统***** |\n");
printf("\t\t\t|_________________________________________________|\n");
printf("\t\t\t| |\n");
printf("\t\t\t|可选项 : |\n");
printf("\t\t\t| 1.显示学生信息 |\n");
printf("\t\t\t| 2.查询学生信息 |\n");
printf("\t\t\t| 3.修改学生信息 |\n");
printf("\t\t\t| 4.删除学生信息 |\n");
printf("\t\t\t| 5.各科成绩各分数段人数表 |\n");
printf("\t\t\t| 0.退出管理系统 |\n");
printf("\t\t\t|_________________________________________________|\n");
printf("请选择:");
scanf("%d", &input);
if (input < 0 || input > 5)
{
printf("输入有误");
Sleep(1000);
fflush(stdin); //防止输入符号时造成多次循环
}
} while (input < 0 || input > 5);
return input;
}
int modifyMenu()
{
int input;
do
{
printf("\t可选项 :\n");
printf("\t\t1.姓名\n");
printf("\t\t2.高数\n");
printf("\t\t3.英语\n");
printf("\t\t4.语文\n");
printf("\t\t0.退出\n");
printf("请选择:");
scanf("%d", &input);
if (input < 0 || input > 4)
{
printf("输入有误\n");
Sleep(1000);
fflush(stdin); //防止输入符号时造成多次循环
}
} while (input < 0 || input > 4);
return input;
}
int idOrName()
{
int input;
do
{
printf("\t可选项 :\n");
printf("\t\t1.学号\n");
printf("\t\t2.姓名\n");
printf("\t\t0.退出\n");
printf("请选择:");
scanf("%d", &input);
if (input < 0 || input > 2)
{
printf("输入有误\n");
Sleep(1000);
fflush(stdin); //防止输入符号时造成多次循环
}
} while (input < 0 || input > 2);
return input;
}
void ranksum() //每进行一次数据修改都重新总分, 排名
{
struct Student *p, *temp;
int i = 1, j;
temp = head;
temp->rank = 1;
p = head->next;
while (p != NULL) //擂台法计算排名
{
temp = head;
p->rank = 1;
for (j = 0; j < i; j++)
{
if (p->sum > temp->sum)
{
temp->rank = temp->rank + 1;
}
else if (p->sum < temp->sum)
{
p->rank = p->rank + 1;
}
temp = temp->next;
}
p = p->next;
i++;
}
}
void createList() //初始化链表
{
int i = 1, j;
FILE *fp;
struct Student *p, *q, *temp;
p = (struct Student *)malloc(LEN);
if ((fp = fopen("./database.txt", "r")) == NULL)
{
printf("open error on reading");
exit(0);
}
//从源文件中读取信息
fscanf(fp, "%d%s%f%f%f", &p->id, p->name, &p->score.gaoshu, &p->score.yingyu, &p->score.yuwen);
p->sum = p->score.gaoshu + p->score.yingyu + p->score.yuwen;
p->rank = 1;
head = p;
while (!feof(fp))
{
q = (struct Student *)malloc(LEN);
fscanf(fp, "%d%s%f%f%f", &q->id, q->name, &q->score.gaoshu, &q->score.yingyu, &q->score.yuwen);
q->sum = q->score.gaoshu + q->score.yingyu + q->score.yuwen;
q->rank = 1;
p->next = q;
p = q;
temp = head; //每一次排名都从第一个节点开始比较
for (j = 0; j < i; j++)
{
if (p->sum > temp->sum)
{
temp->rank = temp->rank + 1;
}
else if (p->sum < temp->sum)
{
p->rank = p->rank + 1;
}
temp = temp->next;
}
i++;
}
p->next = NULL;
fclose(fp);
}
void writeInFile()
{
FILE *fp;
struct Student *p;
p = head;
if ((fp = fopen("./data.txt", "w")) == NULL)
{
printf("open error on writing");
exit(0);
}
while (p)
{
fprintf(fp, "%d\t%s\t%.2f\t%.2f\t%.2f\t%.2f\t %d\n", p->id, p->name, p->score.gaoshu, p->score.yingyu, p->score.yuwen, p->sum, p->rank);
p = p->next;
}
printf("Successfully writing.\n");
fclose(fp);
}
void showOriginalInfo()
{
int i, count = 0;
struct Student *p;
p = head;
printf("学生成绩一览表:\n");
printf("\t -------------------------------------------------------\n\t|");
for (i = 0; i < 7; i++)
{
printf("%2s ", title[i]);
}
printf(" |\n");
while (p)
{
printf("\t|%d\t %s\t%.2f\t%.2f\t%.2f\t%.2f\t %d\t|\n", p->id, p->name, p->score.gaoshu, p->score.yingyu, p->score.yuwen, p->sum, p->rank);
p = p->next;
count++;
}
printf("\t -------------------------------------------------------\n\n");
printf("总人数: %d\n\n", count);
}
void showOneStudentInfo(struct Student *p) //每查询一个学生都输出其个人信息
{
int i;
printf("------------------------\n");
printf("\t");
for (i = 0; i < 7; i++)
{
printf("%2s ", title[i]);
}
printf("\n\t");
printf(" %d\t %s\t%.2f\t%.2f\t%.2f\t%.2f\t %d\n", p->id, p->name, p->score.gaoshu, p->score.yingyu, p->score.yuwen, p->sum, p->rank);
printf("------------------------\n");
}
void queryInfo()
{
struct Student *p;
int flag, i, input, id;
char name[50], ch;
while (1)
{
p = head;
flag = 0;
input = idOrName();
switch (input)
{
case 1:
printf("\n\t输入查询学生学号:");
scanf("%d", &id);
getchar();
Sleep(500);
while (p)
{
if (p->id == id)
{
flag = 1;
break; //查到信息,退出while
}
p = p->next;
}
break;
case 2:
printf("\n\t输入查询学生姓名:");
scanf("%s", name);
getchar();
Sleep(500);
while (p)
{
if (strcmp(p->name, name) == 0)
{
flag = 1;
break; //查到信息,退出while
}
p = p->next;
}
break;
case 0:
Sleep(500);
return;
default:
break;
}
if (flag == 1) //找到了
{
showOneStudentInfo(p); //显示该学生信息
printf("是否继续查询(y/n):");
while (1)
{
scanf("%c", &ch);
fflush(stdin); //清空缓冲区,防止输入多字符
if (ch == 'n' || ch == 'N')
{
return;
}
else if (ch == 'y' || ch == 'Y')
{
break;
}
else
{
printf("错误指令!请重新输入(y/n):");
}
}
}
if (flag == 0)
{
printf("未找到该学生记录,是否重新输入(y/n):");
while (1)
{
scanf("%c", &ch);
fflush(stdin);
if (ch == 'n' || ch == 'N')
{
return;
}
else if (ch == 'y' || ch == 'Y')
{
break;
}
else
{
printf("错误指令!请重新输入(y/n):");
}
}
}
}
}
void modifyInfo()
{
struct Student *p;
p = head;
int flag = 0, i, input, id;
char name[50], ch;
char newName[50];
float newGaoShu, newYingyu, newYuwen;
while (1)
{
p = head;
flag = 0;
input = idOrName();
switch (input)
{
case 1:
printf("\n\t输入查询学生学号:");
scanf("%d", &id);
getchar();
Sleep(500);
while (p)
{
if (p->id == id)
{
flag = 1;
break; //查到信息,退出while
}
p = p->next;
}
break;
case 2:
printf("\n\t输入查询学生姓名:");
scanf("%s", name);
getchar();
Sleep(500);
while (p)
{
if (strcmp(p->name, name) == 0)
{
flag = 1;
break; //查到信息,退出while
}
p = p->next;
}
break;
case 0:
Sleep(500);
return;
default:
break;
}
if (flag == 1)
{
showOneStudentInfo(p); //找到了,显示该学生信息
while (1)
{
input = modifyMenu();
switch (input)
{
case 1:
printf("请输入姓名:");
scanf("%s", newName);
strcpy(p->name, newName);
Sleep(500);
printf("-----------修改成功,继续修改或退出-----------\n------------------------\n");
break;
case 2:
printf("请输入高数成绩:");
scanf("%f", &newGaoShu);
p->score.gaoshu = newGaoShu;
Sleep(500);
printf("-----------修改成功,继续修改或退出-----------\n------------------------\n");
break;
case 3:
printf("请输入英语成绩:");
scanf("%f", &newYingyu);
p->score.yingyu = newYingyu;
Sleep(500);
printf("-----------修改成功,继续修改或退出-----------\n------------------------\n");
break;
case 4:
printf("请输入语文成绩:");
scanf("%f", &newYuwen);
p->score.yuwen = newYuwen;
Sleep(500);
printf("-----------修改成功,继续修改或退出-----------\n------------------------\n");
break;
case 0:
Sleep(500);
break;
default:
break;
}
if (input == 0)
{
p->sum = p->score.gaoshu + p->score.yingyu + p->score.yuwen;
ranksum();
writeInFile(); //重新排序并写入文件
break;
}
}
getchar();
printf("是否继续修改(y/n):");
while (1)
{
scanf("%c", &ch);
fflush(stdin); //清空缓冲区,防止输入多字符
if (ch == 'n' || ch == 'N')
{
return;
}
else if (ch == 'y' || ch == 'Y')
{
break;
}
else
{
printf("错误指令!请重新输入(y/n):");
}
}
}
if (flag == 0)
{
printf("未找到该学生记录,是否重新输入(y/n):");
while (1)
{
scanf("%c", &ch);
fflush(stdin);
if (ch == 'n' || ch == 'N')
{
return;
}
else if (ch == 'y' || ch == 'Y')
{
break;
}
else
{
printf("错误指令!请重新输入(y/n):");
}
}
}
}
}
void deleteInfo()
{
struct Student *r, *p;
int flag, i, input, id;
char name[50], ch;
while (1)
{
p = head;
r = p;
flag = 0;
input = idOrName();
switch (input)
{
case 1:
printf("\n\t输入查询学生学号:");
scanf("%d", &id);
getchar();
Sleep(500);
while (p)
{
if (p->id == id)
{
flag = 1;
break; //查到信息,退出while
}
r = p; //r记录该节点的前一个节点
p = p->next;
}
break;
case 2:
printf("\n\t输入查询学生姓名:");
scanf("%s", name);
getchar();
Sleep(500);
while (p)
{
if (strcmp(p->name, name) == 0)
{
flag = 1;
break; //查到信息,退出while
}
r = p;
p = p->next;
}
break;
case 0:
Sleep(500);
return;
default:
break;
}
if (flag == 1)
{
showOneStudentInfo(p);
printf("是否确定删除?(y/n)");
scanf("%c", &ch);
fflush(stdin); //清空缓冲区,防止输入多字符
if (ch == 'n' || ch == 'N')
{
break;
}
else if (ch == 'y' || ch == 'Y')
{
if (p == head)
{
head = head->next; //头节点则直接删除
}
else
{
r->next = p->next; //该节点的前一个节点指向下一个节点
}
ranksum();
writeInFile(); //重新排序并写入文件
printf("删除成功!\n");
}
else
{
printf("错误指令!请重新输入(y/n):");
}
}
if (flag == 0)
{
printf("未找到该学生记录,是否重新输入(y/n):");
while (1)
{
scanf("%c", &ch);
fflush(stdin);
if (ch == 'n' || ch == 'N')
{
return;
}
else if (ch == 'y' || ch == 'Y')
{
break;
}
else
{
printf("错误指令!请重新输入(y/n):");
}
}
}
printf("是否继续删除(y/n):");
while (1)
{
scanf("%c", &ch);
fflush(stdin); //清空缓冲区,防止输入多字符
if (ch == 'n' || ch == 'N')
{
return;
}
else if (ch == 'y' || ch == 'Y')
{
break;
}
else
{
printf("错误指令!请重新输入(y/n):");
}
}
}
}
void showData()
{
struct Student *p;
int i;
FILE *fp;
char str[6][30] = { "0 - 60", "60 - 70", "70 - 80", "80 - 90", "90 - 100", "总人数" };
p = head;
int people[3][6] = { 0 }; //横列人数
int allpeople[5] = { 0 }; //纵列相加的人数
float score[3] = { 0.0 };
//计算分数段人数
while (p)
{
score[0] = p->score.gaoshu;
score[1] = p->score.yingyu;
score[2] = p->score.yuwen;
for (i = 0; i < 3; i++)
{
if ((score[i] >= 0) && (score[i] <= 60))
{
people[i][0] += 1;
}
else if ((score[i] > 60) && (score[i] <= 70))
{
people[i][1] += 1;
}
else if ((score[i] > 70) && (score[i] <= 80))
{
people[i][2] += 1;
}
else if ((score[i] > 80) && (score[i] <= 90))
{
people[i][3] += 1;
}
else if ((score[i] > 90) && (score[i] <= 100))
{
people[i][4] += 1;
}
people[i][5] = people[i][0] + people[i][1] + people[i][2] + people[i][3] + people[i][4];
}
p = p->next;
}
for (i = 0; i < 5; i++)
{
allpeople[i] = people[0][i] + people[1][i] + people[2][i];
}
//显示信息
printf("\n各科分数分段表:");
printf("\n\n------------------------\n\t ");
for (i = 0; i < 6; i++)
{
printf("%s ", str[i]);
}
printf("\n\n高数");
for (i = 0; i < 6; i++)
{
printf(" %2d", people[0][i]);
}
printf("\n\n英语");
for (i = 0; i < 6; i++)
{
printf(" %2d", people[1][i]);
}
printf("\n\n语文");
for (i = 0; i < 6; i++)
{
printf(" %2d", people[2][i]);
}
printf("\n\n总人数");
for (i = 0; i < 5; i++)
{
printf(" %2d ", allpeople[i]);
}
printf("\n\n------------------------\n\n");
//写入文件
if ((fp = fopen("./people_info.txt", "w")) == NULL)
{
printf("open error on writing");
exit(0);
}
fputs("\n各科分数分段表:\n\n------------------------\n ", fp);
for (i = 0; i < 6; i++)
{
fputs(" ", fp);
fputs(str[i], fp);
}
fputs("\n\n高数", fp);
fprintf(fp, " %3d %3d %3d %3d %3d %3d\n", people[0][0], people[0][1], people[0][2], people[0][3], people[0][4], people[0][5]);
fputs("\n\n英语", fp);
fprintf(fp, " %3d %3d %3d %3d %3d %3d\n", people[1][0], people[1][1], people[1][2], people[1][3], people[1][4], people[1][5]);
fputs("\n\n语文", fp);
fprintf(fp, " %3d %3d %3d %3d %3d %3d\n", people[2][0], people[2][1], people[2][2], people[2][3], people[2][4], people[2][5]);
fputs("\n\n总人数", fp);
fprintf(fp, " %3d %3d %3d %3d %3d\n", allpeople[0], allpeople[1], allpeople[2], allpeople[3], allpeople[4]);
fputs("\n\n------------------------\n\n", fp);
fclose(fp);
}
#include "func.h"
int main()
{
login();
Sleep(1500);
createList(); //初始化链表信息
writeInFile(); //将处理后的信息写入目标文件
while (1)
{
switch (menu())
{
case 1:
system("cls");
printf("\n显示学生信息,内部逻辑处理中......\n\n");
Sleep(500);
system("cls");
showOriginalInfo();
break;
case 2:
system("cls");
printf("\n查询学生信息,内部逻辑处理中......\n\n");
Sleep(500);
system("cls");
queryInfo();
break;
case 3:
system("cls");
printf("\n修改学生信息,内部逻辑处理中......\n\n");
Sleep(500);
system("cls");
modifyInfo();
break;
case 4:
system("cls");
printf("\n删除学生信息,内部逻辑处理中......\n\n");
Sleep(500);
system("cls");
deleteInfo();
break;
case 5:
system("cls");
printf("\n各科成绩各分数段人数表,内部逻辑处理中......\n\n");
Sleep(500);
system("cls");
showData();
break;
case 0:
system("cls");
printf("\n\n\t\t\t-------------------感谢使用!-------------------\n\n\n");
Sleep(500);
exit(-1);
break;
default:
break;
}
system("PAUSE");
}
return 0;
}