#include <stdlib.h>
struct course {
int math;
int computer;
int English;
int PE;
};
struct stu {
char name[100];
int age;
char sex;
struct course subject;
struct stu* next;
char number[20];
int all_scores;
int average_scores;
int idx ;
};
void menu(void) {
printf("**************************\n"
"*******学生管理系统*******\n"
"**************************\n"
"*******系统功能菜单*******\n"
"--------------------------\n"
"**************************\n"
"*** 1.增加学生信息 ***\n"//ok
"*** 2.查询学生信息 ***\n"//ok
"*** 3.删除学生信息 ***\n"//ok
"*** 4.修改学生信息 ***\n"//ok
"***** 5.读取文件 *****\n"//ok
"*** 6.显示学生信息 ***\n"//ok
"***** 7.学科详情 *****\n"//ok
"****** 8.菜单帮助 *****\n"//ok
"***** 0.退出系统 *****\n"//ok
);
}
int main() {
FILE* fp = fopen("D:\\Shelly\\OneDrive\\桌面\\无标题.txt","a+");
int n;
struct stu *head = (struct stu*)malloc(sizeof(struct stu));
head->next = NULL;
menu();
fseek(fp, 0, SEEK_SET);
while (1) {
printf("\n请输入菜单编号:\n");
scanf("%d", &n);
switch (n) {
case 1:
{
struct stu* new_stu = (struct stu*)malloc(sizeof(struct stu));
printf("请输入学生姓名:");
scanf("%s", new_stu->name);
printf("请输入学生学号:");
scanf("%s", &(new_stu->number));
printf("请输入学生年龄:");
scanf("%d", &(new_stu->age));
printf("请输入学生性别(M/F):");
scanf(" %c", &(new_stu->sex));
printf("请输入数学成绩:");
scanf("%d", &(new_stu->subject.math));
printf("请输入计算机成绩:");
scanf("%d", &(new_stu->subject.computer));
printf("请输入英语成绩:");
scanf("%d", &(new_stu->subject.English));
printf("请输入体育成绩:");
scanf("%d", &(new_stu->subject.PE));
new_stu->all_scores = new_stu->subject.math + new_stu->subject.computer + new_stu->subject.PE + new_stu->subject.English;
new_stu->average_scores = (new_stu->all_scores) / 4;
new_stu->next = head->next;
head->next = new_stu;
fprintf(fp, "姓名:%s\n", new_stu->name);
fprintf(fp, "学号:%s\n", new_stu->number);
fprintf(fp, "年龄:%d\n", new_stu->age);
fprintf(fp, "性别:%c\n", new_stu->sex);
fprintf(fp, "数学成绩:%d\n", new_stu->subject.math);
fprintf(fp, "计算机成绩:%d\n", new_stu->subject.computer);
fprintf(fp, "英语成绩:%d\n", new_stu->subject.English);
fprintf(fp, "体育成绩:%d\n", new_stu->subject.PE);
fprintf(fp, "总分:%d\n", new_stu->all_scores);
fprintf(fp, "平均分:%d\n\n", new_stu->average_scores);
fseek(fp, 0, SEEK_SET);
system("cls");
printf("添加学生成功!!!\n");
break;
}
case 2:
{
fseek(fp, 0, SEEK_SET);
printf("请选择你的查询方式:\n");
printf("C(学号查询)||N(姓名查询)\n");
char c;
int index = 0;
scanf(" %c", &c);
struct stu student;
if (c == 'C') {
printf("请输入要查找学生的学号:\n");
char k[20];
scanf("%s", k);
while (fscanf(fp, "姓名:%s\n学号:%s\n年龄:%d\n性别:%c\n数学成绩:%d\n计算机成绩:%d\n英语成绩:%d\n体育成绩:%d\n总分:%d\n平均分:%d\n\n",
student.name, &(student.number), &(student.age), &(student.sex), &(student.subject.math), &(student.subject.computer),
&(student.subject.English), &(student.subject.PE), &(student.all_scores), &(student.average_scores)) != EOF) {
if (strcmp(student.number, k) == 0) {
index = 1;
break;
}
}
}
if (c == 'N') {
char search_name[100];
printf("请输入要查找的学生姓名:");
scanf("%s", search_name);
while (fscanf(fp, "姓名:%s\n学号:%s\n年龄:%d\n性别:%c\n数学成绩:%d\n计算机成绩:%d\n英语成绩:%d\n体育成绩:%d\n总分:%d\n平均分:%d\n\n",
student.name, &(student.number), &(student.age), &(student.sex), &(student.subject.math), &(student.subject.computer),
&(student.subject.English), &(student.subject.PE), &(student.all_scores), &(student.average_scores)) != EOF) {
if (strcmp(student.name, search_name) == 0) {
index = 1;
break;
}
}
}
if (index == 0) {
printf("该学生不存在\n");
break;
}
else{
printf("姓名:%s\n", student.name);
printf("学号:%s\n", student.number);
printf("年龄:%d\n", student.age);
printf("性别:%c\n", student.sex);
printf("数学成绩:%d\n", student.subject.math);
printf("计算机成绩:%d\n", student.subject.computer);
printf("英语成绩:%d\n", student.subject.English);
printf("体育成绩:%d\n", student.subject.PE);
printf("总分:%d\n", student.all_scores);
printf("平均分:%d\n", student.average_scores);
break;}
}
case 3:
{
printf("请确保在删除前读取过文件!!!\n");
printf("请输入您想要删除学生的学号:\n");
char del_number[20];
getchar();
gets(del_number);
struct stu* p = head;
struct stu* temp;
int index = 0;
for (p; p->next; p = p->next) {
if (strcmp(p->next->number, del_number) == 0) {
temp = p->next;
p->next = p->next->next;
free(temp);
index = 1;
break;
}
}
if (index == 0) {
printf("该学生不存在!");
}
else {
fclose(fp);
fp = fopen("D:\\Shelly\\OneDrive\\桌面\\无标题.txt", "w+");
if (fp == NULL) {
printf("文件打开失败!\n");
return;
}
for (p = head->next; p != NULL; p = p->next) {
fprintf(fp, "姓名:%s\n学号:%s\n年龄:%d\n性别:%c\n数学成绩:%d\n计算机成绩:%d\n英语成绩:%d\n体育成绩:%d\n总分:%d\n平均分:%d\n\n",
p->name, p->number, p->age, p->sex, p->subject.math, p->subject.computer, p->subject.English, p->subject.PE, p->all_scores, p->average_scores);
fflush(fp);
}
}
system("cls");
printf("删除学生成功!!!\n");
break;
}
case 4:
{
printf("请确保在修改前读取过文件!!!\n");
printf("请输入您想要修改学生信息的学号:\n");
char mod_number[20];
getchar();
gets(mod_number);
struct stu* p = head;
struct stu* temp;
int index = 0;
for (p; p->next; p = p->next) {
if (strcmp(p->next->number, mod_number) == 0) {
temp = p->next;
p->next = p->next->next;
free(temp);
index = 1;
break;
}
}
if (index == 0) {
printf("该学生不存在!");
}
else {
printf("请输入修改后的信息:\n");
struct stu* new_stu = (struct stu*)malloc(sizeof(struct stu));
printf("请输入学生姓名:");
scanf("%s", new_stu->name);
printf("请输入学生学号:");
scanf("%s", &(new_stu->number));
printf("请输入学生年龄:");
scanf("%d", &(new_stu->age));
printf("请输入学生性别(M/F):");
scanf(" %c", &(new_stu->sex));
printf("请输入数学成绩:");
scanf("%d", &(new_stu->subject.math));
printf("请输入计算机成绩:");
scanf("%d", &(new_stu->subject.computer));
printf("请输入英语成绩:");
scanf("%d", &(new_stu->subject.English));
printf("请输入体育成绩:");
scanf("%d", &(new_stu->subject.PE));
new_stu->all_scores = new_stu->subject.math + new_stu->subject.computer + new_stu->subject.PE + new_stu->subject.English;
new_stu->average_scores = (new_stu->all_scores) / 4;
new_stu->next = head->next;
head->next = new_stu;
fclose(fp);
fp = fopen("D:\\Shelly\\OneDrive\\桌面\\无标题.txt", "w+");
for (p = head->next; p != NULL; p = p->next) {
fprintf(fp, "姓名:%s\n学号:%s\n年龄:%d\n性别:%c\n数学成绩:%d\n计算机成绩:%d\n英语成绩:%d\n体育成绩:%d\n总分:%d\n平均分:%d\n\n",
p->name, p->number, p->age, p->sex, p->subject.math, p->subject.computer, p->subject.English, p->subject.PE, p->all_scores, p->average_scores);
}
}
break;
}
case 5: {
FILE* ffp = fopen("D:\\Shelly\\OneDrive\\桌面\\无标题.txt", "r");
fseek(fp, 0, SEEK_SET);
struct stu student;
while (fscanf(fp, "姓名:%s\n学号:%s\n年龄:%d\n性别:%c\n数学成绩:%d\n计算机成绩:%d\n英语成绩:%d\n体育成绩:%d\n总分:%d\n平均分:%d\n\n",
student.name, &(student.number), &(student.age), &(student.sex), &(student.subject.math), &(student.subject.computer),
&(student.subject.English), &(student.subject.PE), &(student.all_scores), &(student.average_scores)) != EOF) {
int k = student.number;
struct stu *p;
p = head;
int index = 0;
for (p; p; p = p->next) {
if (p->number == k) {
index = 1;
break;
}
}
if (index) {
continue;
}
else
{
struct stu* new_stu = (struct stu*)malloc(sizeof(struct stu));
strcpy(new_stu->name, student.name);
strcpy(new_stu->number, student.number);
new_stu->age = student.age;
new_stu->sex = student.sex;
new_stu->subject.math = student.subject.math;
new_stu->subject.computer = student.subject.computer;
new_stu->subject.English = student.subject.English;
new_stu->subject.PE = student.subject.PE;
new_stu->all_scores = new_stu->subject.math + new_stu->subject.computer + new_stu->subject.PE + new_stu->subject.English;
new_stu->average_scores = (new_stu->all_scores) / 4.0;
new_stu->next = head->next;
head->next = new_stu;
}
}
fclose(ffp);
printf("读取成功!\n");
break;
}
case 6: {
system("cls");
struct stu* p = head->next;
while (p != NULL) {
printf("姓名:%s ", p->name);
printf("学号:%s ", p->number);
printf("年龄:%d ", p->age);
printf("性别:%c ", p->sex);
printf("数学成绩:%d ", p->subject.math);
printf("计算机成绩:%d ", p->subject.computer);
printf("英语成绩:%d ", p->subject.English);
printf("体育成绩:%d ", p->subject.PE);
printf("总分:%d ", p->all_scores);
printf("平均分:%d\n", p->average_scores);
p = p->next;
}
break;
}
case 7: {
system("cls");
struct stu* p = head->next;
if (p == NULL) {
printf("学生信息为空!\n");
}
else {
int k = 0;
int arr[1000] = { 0 };
while (p) {
arr[k] = p->all_scores;
p->idx = 1;
p = p->next;
k++;
}
int q = k;
while (q) {
for (int i = 0; i < q - 1; i++) {
if (arr[i] < arr[i + 1]) {
int c = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = c;
}
}
q--;
}
int j = k,i=0;
while (j) {
p = head->next;
for (p; p; p = p->next) {
if (p->idx == 1 && p->all_scores == arr[i]) {
printf("姓名:%s ", p->name);
printf("学号:%s ", p->number);
printf("数学成绩:%d ", p->subject.math);
printf("计算机成绩:%d ", p->subject.computer);
printf("英语成绩:%d ", p->subject.English);
printf("体育成绩:%d ", p->subject.PE);
printf("总分:%d ", p->all_scores);
printf("平均分:%d\n", p->average_scores);
p->idx = 0;
i++;
}
}
j--;
}
break;
}}
case 8: {
menu();
break;
}
case 0:
{
fclose(fp);
printf("正在为您退出系统.\n");
return 0;
}
default:
printf("您的输入无效,请重新输入:\n");
break;
}
}
return 0;
}
尚未解决的问题: 第一,我在学科和学生信息中设置的元素过多,没有考虑到,如果是竖着排版的话,会影响阅读,解决方案的话控制换行符和格式化输出一下就可以解决,目前已解决,不过个人觉得还是不够美。
第二个问题,我对部分非法输入进行了判别,还有部分非法输入,例如,在写入成绩的时候,如果不小心输了字母,会导致文件读写出错,解决的方案是将int类型转换为char类型,并且判断输入的是否符合格式,不符直接打回。
第三个问题,按要求应该是用函数,而不是全部写在main函数中,不过我个人觉得这种case分支,阅读和修改起来也不是很麻烦,解决方案的话,就是改为函数形式就行了。
第四个问题,起初我没有考虑到,如果是重名怎么办?当然,我修改了这个问题,所以后续的操作基本上都是学号进行,但是我保留了查询学生中的姓名查询,毕竟能让功能看起来更多样化一点,解决方案就是删除这一部分,或者说让他一直读下去,读到EOF为止。
第五个问题,本系统支持文件读写,事实上,即使在文件中,存在学生的信息,如果不提前按5,进行读入那么链表是空的,这就是如果写的是函数接口的好处,这样可以直接在开头处进行一次调用,我的解决方案就是引导用户来按下这个5。