写一个简单的学生成绩管理系统
为了方便,并且这个程序也不是很长,所以把所有代码写在一起了,下面是头文件和声明部分:
4.14修改版 :
#include
#include
#include
#define SIZE 20
typedef struct Student * List;
void over(); //释放空间
void Show(); //显示整个表
void find(); //找到某个学生的信息
void sort(); //排序
void showmenu(); //菜单
void I_Change(); //更改学号
void N_Change(); //更改姓名
void S_Change(); //更改分数
void average(); //显示平均分数、总人数
List add(); //增加学生信息
List Body(); //主体信息
List readin(); //文件读入
List I_Delete(); //按学号删除学生信息
List N_Delete(); //按姓名删除学生信息
释放空间的函数(这里顺序不是很好,不过不影响程序运行):
void over(List head) //释放空间
{
List current, missing;
current = head;missing = current->next;
if (current == NULL)
printf("The list is empty!\n");
else
{
while (current != NULL)
{
free(current);
current = missing;
missing = missing->next;
}
}
}
输出数据的部分:
这里用虚线来分隔每个不同学生的成绩
void Show(List head) //显示整个表
{
List current;
current = head;
if (current == NULL) //判断表是否为空
printf("The list is empty!\n");
else
{
printf("----------------------------------\n");
printf("ID score name\n");
printf("----------------------------------\n");
while (current)
{
printf("%d %.2lf %s \n", current->Id, current->score, current->name);
printf("----------------------------------\n");
current = current->next; //向后遍历
}
}
}
菜单栏:
void showmenu()
{
printf("------------------------ student management system---------------------\n");
printf("- 1 to show the all list. 2 to change student data -\n");
printf("- 3 to delete the student message. 4 to add student message -\n");
printf("- 5 to add message from files 6 to sort student message -\n");
printf("- 7 to get the average and total score 8 to show one student`s message-\n");
printf("- other numbers to quit -\n");
printf("-----------------------------------------------------------------------\n");
printf("Please enter number to choose(0-9):");
}
改变ID:
void I_Change(List head, int O_Id, int N_Id) //更改学号
{
struct Student *current;
current = head;
if (current == NULL)
printf("The list is empty!\n");
else
{
while (current->next != NULL && current->Id != O_Id)
current = current->next;
if (current->Id == O_Id)
current->Id = N_Id;
else
printf("404 no find\n");
}
}
更改姓名:
void N_Change(List head, int O_Id, char N_name[]) //更改姓名
{
List current;
current = head;
if (current == NULL)
printf("The list is empty!\n");
else
{
while (current->next != NULL && current->Id != O_Id)
current = current->next;
if (current->Id == O_Id)
strcpy(current->name, N_name);
else
printf("404 no find\n");
}
}
更改成绩:
void S_Change(List head, int O_Id, double N_score) //更改分数
{
List current;
current = head;
if (current == NULL)
printf("The list is empty!\n");
else
{
while (current->next != NULL && current->Id != O_Id)
current = current->next;
if (current->Id == O_Id)
current->score = N_score;
else
printf("404 no find\n");
}
}
主体部分:
List Body(int ask, List head)
{
int O_Id, N_Id, num;
double N_score;
char N_name[SIZE];
if (ask == 1)
Show(head); //显示整个表
else if (ask == 2) //更改数据
{
printf("Please enter which student you want to change (please enter Id)\n");
scanf("%d", &O_Id);
printf("If you want to change the Id of the student please enter \"1\"\n");
printf("If you want to change the name of the student please enter\"2\"\n");
printf("If your want to change the score of the student please enter\"3\"\n");
printf("If you don`t want to change please enter other numbers\n");
scanf("%d", &num);
if (num == 1) //更改学号
{
printf("Please enter the new Id:\n");
scanf("%d", &N_Id);
I_Change(head, O_Id, N_Id);
}
else if (num == 2) //更改学生姓名
{
printf("Plese enter the new name\n");
scanf("%s", N_name);
N_Change(head, O_Id, N_name);
}
else if (num == 3) // 更改学生分数
{
printf("Please enter the new score:\n");
scanf("%lf", &N_score);
S_Change(head, O_Id, N_score);
}
}
else if (ask == 3) //删除数据
{
printf("If you want to use the Id to delete the message,plesea eneter\"1\"\n");
printf("If you want to use the name to delete the message ,Please enter\"2\"\n");
scanf("%d", &ask);
if (ask == 1) //按学号查找
{
printf("(Enter the Id of the student)\n");
scanf("%d", &O_Id);
head = I_Delete(head, O_Id);
}
else if (ask == 2) //按姓名查找
{
printf("Enter the name of the student\n");
scanf("%s", &N_name);
head = N_Delete(head, N_name);
}
}
else if (ask == 4) //添加数据
{
printf("If you want to add the student message before the student you choose please enter 1\n");
printf("If you want to add the student message after the student you choose please enter 2\n");
scanf("%d", &num);
printf("please enter the name 、Id and score of the new student\n");
scanf("%s%d%lf", &N_name, &N_Id, &N_score);
head = add(head, N_name, N_Id, N_score, num);
}
else if (ask == 5)
head = readin();
else if (ask == 6)
sort(head);
else if (ask == 7)
average(head);
else if (ask == 8)
find(head);
else
{
printf("Thank you to use!\n");
over(head); //释放所有空间
}
system("pause");
system("CLS");
showmenu();
return head;
}
新增学生成绩,在某个学生前插入其他学生成绩部分没有问题,但是在第一个学生后插入其他学生成绩后输出数据时程序会崩溃,但是在非第一个学生后插入其他学生成绩却没有问题,不知道为什么。
原因在于我写的代码当current==head 的时候在赋值给after的语句那边直接跳过,导致after没有被赋值,此时after的值是垃圾值,从而导致整个链表断裂,新增一句语句:
if(current ==head)
after=current->next;
就能解决这个问题。
由于在前面插入信息如果current==head 的时候刚好before没有值,所以before没有出现问题。
代码如下:
List add(List head, char N_name[], int N_Id, double N_score,int num) //增加信息
{
List current, before, addin, after;
int O_Id;
current = head;
if (current == NULL)
{
addin = (List)malloc(sizeof(struct Student));
head = addin;
addin->next = NULL;
addin->Id = N_Id;addin->score = N_score;strcpy(addin->name, N_name);
return head;
}
else
{
printf("please enter the student`s Id\n"); //通过定位下一位学生来找到要插入的成绩应该放在哪里
scanf("%d", &O_Id);
while (current->next != NULL && current->Id != O_Id)
{
before = current;
current = current->next;
after = current->next;
}
if(current ==head)
after=current->next;
if (current->Id = O_Id)
{
addin = (struct Student*)malloc(sizeof(struct Student)); //为新结点动态分配空间
if(num==1)
{
if (current == head)
{
addin->next = current;
addin->Id = N_Id;addin->score = N_score;strcpy(addin->name, N_name);
return addin;
}
else
{
before->next = addin;
addin->next = current;
addin->Id = N_Id;addin->score = N_score;strcpy(addin->name, N_name);
return head;
}
}
else
{
current->next = addin;
addin->Id = N_Id;addin->score = N_score;strcpy(addin->name, N_name);
addin->next = after;
return head;
}
}
else
printf("404 no find!\n");
}
return head;
}
读入数据,这个部分使用的是文件流,但是不知道为什么有时候使用这个功能会让整个程序崩溃,有时候又能使用.
刚刚找到了问题,是后面动态分配的时候分配的空间大小出现了问题。
正确代码如下:
List readin()
{
FILE * fp;
List head, current, record;
char name[SIZE];
int Id; double score;
head = NULL;
if ((fp = fopen("D:\\tom and his firends\\development\\code\\c c++\\program\\学生管理系统\\message.txt", "r")) == NULL) //判断文件是否存在
{
printf("fali to open the flie!\n");
exit(0);
}
while (~fscanf(fp,"%s", name)) //读入数据
{
current = (List)malloc(sizeof(struct Student ));
if (head == NULL)
head = current;
else
record->next = current;
fscanf(fp, "%d %lf", &Id, &score);
strcpy(current->name, name);current->Id = Id;current->score = score;
current->next = NULL;
record = current;
}
fclose(fp);
return head;
}
按学号删除学生信息:
List I_Delete(List head, int O_Id) //按学号查找并删除数据
{
List current, missing;
current = head;
if (current == NULL)
printf("The list is empty!\n");
else
{
while (current->next != NULL && current->Id != O_Id) //当查找到该需要修改的元素或者查找完整个表
{
missing = current;
current = current->next;
}
if (current->Id == O_Id)
{
if (current == head)
{
head = current->next;
free(current);
return head;
}
else
missing->next = current->next;
free(current);
}
else
printf("404 no find\n");
}
return head;
}
按姓名删除学生信息:
List N_Delete(List head, char N_name[]) //按姓名查找并删除数据
{
List current, missing;
current = head;
if (current == NULL)
printf("The list is empty!\n");
else
{
while (current->next != NULL && strcmp(current->name, N_name) != 0) //当查找到该需要修改的元素或者查找完整个表
{
missing = current; //记录当前结点的前一个结点
current = current->next;
}
if (strcmp(current->name, N_name) == 0)
{
if (current == head)
{
head = current->next;
free(current);
return head;
}
else
missing->next = current->next;
free(current);
}
else
printf("404 no find\n");
}
return head;
}
主函数部分:
int main(void)
{
List head;
int ask;
head = NULL;
showmenu();
scanf("%d", &ask);
while (ask)
{
head = Body(ask, head);
scanf("%d", &ask);
}
return 0;
}
4.14版本新增了排序功能,两种排序方法一个是按学号排序(从小到大)另外一个是按成绩排序(从大到小)还有计算平均成绩、总成绩、显示学生人数和显示某个学生的成绩。
排序代码如下:
void sort(List head)
{
int ask;List current, record;int n, i;char name[SIZE];int Id;double score;
struct Student change;
current = head;
if (current == NULL) //判断当前表是否为空
{
printf("The list is empty!\n");
return;
}
for (;current;current = current->next) n++; //记录当前有多少人,即进行多少次循环
current = head;
printf("If you want to sort the student message by score,please enter 1\n");
printf("If you want to sort the student message by Id ,please enter 2\n");
scanf("%d", &ask);
if (ask == 1)
{
for (i = 0;i < n;i++)
{
while (current->next)
{
record = current->next;
if (current->score < record->score)
{
strcpy(name, current->name); Id = current->Id;score = current->score;
strcpy(current->name, record->name), current->Id = record->Id;current->score = record->score;
strcpy(record->name, name), record->Id = Id;record->score = score;
}
current = current->next;
}
current = head;
}
}
else
{
current = head;
for (i = 0;i < n;i++)
{
while (current->next)
{
record = current->next;
if (current->Id > record->Id)
{
strcpy(name, current->name); Id = current->Id;score = current->score;
strcpy(current->name, record->name), current->Id = record->Id;current->score = record->score;
strcpy(record->name, name), record->Id = Id;record->score = score;
}
current = current->next;
}
current = head;
}
}
}
计算平均成绩、总成绩、显示学生人数 代码如下:
void average(List head)
{
List current;
float total = 0;int Tperson = 0;float average = 0;
current = head;
if (current == NULL)
{
printf("the list is empty!\n");
return ;
}
while (current)
{
total += current->score;Tperson++;
current = current->next; //向后遍历;
}
if (Tperson != 0) average = total / Tperson;
printf("the total score is %.2f,the total person is %d,the average socre is %.2f\n", total, Tperson, average);
}
显示某个学生成绩代码如下:
void find(List head)
{
int ask;char name[SIZE];int Id;List current;
current = head;
if (current == NULL)
{
printf("The list is empty\n");
return;
}
printf("If you want to find the student by Id,please enter 1\n");
printf("If you want to find the student by name,please enter 2\n");
scanf("%d", &ask);
if (ask == 1)
{
printf("Please enter the Id of the student you want to find\n");
scanf("%d", &Id);
while (current->next != NULL && current->Id != Id)
current = current->next;
if (current->Id == Id)
{
printf("----------------------------------\n");
printf("ID score name\n");
printf("----------------------------------\n");
printf("%d %.2lf %s \n", current->Id, current->score, current->name);
printf("----------------------------------\n");
}
else
printf("404 no find\n");
}
else if (ask == 2)
{
printf("Please enter the name of the student you want to find\n");
scanf("%s", name);
while (current->next != NULL && strcmp(current->name, name) != 0)
current = current->next;
if (strcmp(current->name, name) == 0)
{
printf("----------------------------------\n");
printf("ID score name\n");
printf("----------------------------------\n");
printf("%d %.2lf %s \n", current->Id, current->score, current->name);
printf("----------------------------------\n");
}
else
printf("404 no find\n");
}
}
一点感想:做这个学生管理系统简易版虽然花的时间不算特别长,但其实也不短了,其中修修改改,遇到很多很多的bug和自己编写程序中出现的问题,虽然耗费了不少精力,但是对于链表和指针的概念有进一步的提高,多打代码还是有很大的提升的,接下来不打算再修改这段代码了,虽然写的不算好,甚至只是初窥门径,但是我以后会更加努力去写出更优秀的代码,如果以后重写这个程序的话应该会从头开始,用更好的思想来写下这个程序。通过这个程序,我明白自己的实力远远不够,所以我还是要再接再厉,但是这个程序从别人的一句话到自己想要去真正的实现,感觉还是挺梦幻的,给自己一点鼓励,能写出这个程序我也学到了不少。
4.14版本 完整代码如下:
#include
#include
#include
#define SIZE 20
typedef struct Student * List;
void over(); //释放空间
void Show(); //显示整个表
void find(); //找到某个学生的信息
void sort(); //排序
void showmenu(); //菜单
void I_Change(); //更改学号
void N_Change(); //更改姓名
void S_Change(); //更改分数
void average(); //显示平均分数、总人数
List add(); //增加学生信息
List Body(); //主体信息
List readin(); //文件读入
List I_Delete(); //按学号删除学生信息
List N_Delete(); //按姓名删除学生信息
struct Student
{
int Id;char name[SIZE];double score;
List next;
};
int main(void)
{
List head;
int ask;
head = NULL;
showmenu();
scanf("%d", &ask);
while (ask)
{
head = Body(ask, head);
scanf("%d", &ask);
}
return 0;
}
//菜单
void showmenu()
{
printf("------------------------ student management system---------------------\n");
printf("- 1 to show the all list. 2 to change student data -\n");
printf("- 3 to delete the student message. 4 to add student message -\n");
printf("- 5 to add message from files 6 to sort student message -\n");
printf("- 7 to get the average and total score 8 to show one student`s message-\n");
printf("- other numbers to quit -\n");
printf("-----------------------------------------------------------------------\n");
printf("Please enter number to choose(0-9):");
}
//显示整个表
void Show(List head)
{
List current;
current = head;
if (current == NULL) //判断表是否为空
printf("The list is empty!\n");
else
{
printf("----------------------------------\n");
printf("ID score name\n");
printf("----------------------------------\n");
while (current)
{
printf("%d %.2lf %s \n", current->Id, current->score, current->name);
printf("----------------------------------\n");
current = current->next; //向后遍历
}
}
}
//释放空间
void over(List head)
{
List current, missing;
current = head;missing = current->next;
if (current == NULL)
printf("The list is empty!\n");
else
{
while (current != NULL)
{
free(current);
current = missing;
missing = missing->next;
}
}
}
//更改学号
void I_Change(List head, int O_Id, int N_Id)
{
struct Student *current;
current = head;
if (current == NULL)
printf("The list is empty!\n");
else
{
while (current->next != NULL && current->Id != O_Id)
current = current->next;
if (current->Id == O_Id)
current->Id = N_Id;
else
printf("404 no find\n");
}
}
//更改姓名
void N_Change(List head, int O_Id, char N_name[])
{
List current;
current = head;
if (current == NULL)
printf("The list is empty!\n");
else
{
while (current->next != NULL && current->Id != O_Id)
current = current->next;
if (current->Id == O_Id)
strcpy(current->name, N_name);
else
printf("404 no find\n");
}
}
//更改分数
void S_Change(List head, int O_Id, double N_score)
{
List current;
current = head;
if (current == NULL)
printf("The list is empty!\n");
else
{
while (current->next != NULL && current->Id != O_Id)
current = current->next;
if (current->Id == O_Id)
current->score = N_score;
else
printf("404 no find\n");
}
}
//按学号查找并删除数据
List I_Delete(List head, int O_Id)
{
List current, missing;
current = head;
if (current == NULL)
printf("The list is empty!\n");
else
{
while (current->next != NULL && current->Id != O_Id) //当查找到该需要修改的元素或者查找完整个表
{
missing = current;
current = current->next;
}
if (current->Id == O_Id)
{
if (current == head)
{
head = current->next;
free(current);
return head;
}
else
missing->next = current->next;
free(current);
}
else
printf("404 no find\n");
}
return head;
}
//按姓名查找并删除数据
List N_Delete(List head, char N_name[])
{
List current, missing;
current = head;
if (current == NULL)
printf("The list is empty!\n");
else
{
while (current->next != NULL && strcmp(current->name, N_name) != 0) //当查找到该需要修改的元素或者查找完整个表
{
missing = current; //记录当前结点的前一个结点
current = current->next;
}
if (strcmp(current->name, N_name) == 0)
{
if (current == head)
{
head = current->next;
free(current);
return head;
}
else
missing->next = current->next;
free(current);
}
else
printf("404 no find\n");
}
return head;
}
//增加信息
List add(List head, char N_name[], int N_Id, double N_score, int num)
{
List current, before, addin, after;
int O_Id;
current = head;
if (current == NULL)
{
addin = (List)malloc(sizeof(struct Student));
head = addin;
addin->next = NULL;
addin->Id = N_Id;addin->score = N_score;strcpy(addin->name, N_name);
return head;
}
else
{
printf("please enter the student`s Id\n"); //通过定位下一位学生来找到要插入的成绩应该放在哪里
scanf("%d", &O_Id);
while (current->next != NULL && current->Id != O_Id)
{
before = current;
current = current->next;
after = current->next;
}
if (current == head)
after = current->next;
if (current->Id = O_Id)
{
addin = (struct Student*)malloc(sizeof(struct Student)); //为新结点动态分配空间
if (num == 1)
{
if (current == head)
{
addin->next = current;
addin->Id = N_Id;addin->score = N_score;strcpy(addin->name, N_name);
return addin;
}
else
{
before->next = addin;
addin->next = current;
addin->Id = N_Id;addin->score = N_score;strcpy(addin->name, N_name);
return head;
}
}
else
{
current->next = addin;
addin->Id = N_Id;addin->score = N_score;strcpy(addin->name, N_name);
addin->next = after;
return head;
}
}
else
printf("404 no find!\n");
}
return head;
}
//主体信息
List Body(int ask, List head)
{
int O_Id, N_Id, num;
double N_score;
char N_name[SIZE];
if (ask == 1)
Show(head); //显示整个表
else if (ask == 2) //更改数据
{
printf("Please enter which student you want to change (please enter Id)\n");
scanf("%d", &O_Id);
printf("If you want to change the Id of the student please enter \"1\"\n");
printf("If you want to change the name of the student please enter\"2\"\n");
printf("If your want to change the score of the student please enter\"3\"\n");
printf("If you don`t want to change please enter other numbers\n");
scanf("%d", &num);
if (num == 1) //更改学号
{
printf("Please enter the new Id:\n");
scanf("%d", &N_Id);
I_Change(head, O_Id, N_Id);
}
else if (num == 2) //更改学生姓名
{
printf("Plese enter the new name\n");
scanf("%s", N_name);
N_Change(head, O_Id, N_name);
}
else if (num == 3) // 更改学生分数
{
printf("Please enter the new score:\n");
scanf("%lf", &N_score);
S_Change(head, O_Id, N_score);
}
}
else if (ask == 3) //删除数据
{
printf("If you want to use the Id to delete the message,plesea eneter\"1\"\n");
printf("If you want to use the name to delete the message ,Please enter\"2\"\n");
scanf("%d", &ask);
if (ask == 1) //按学号查找
{
printf("(Enter the Id of the student)\n");
scanf("%d", &O_Id);
head = I_Delete(head, O_Id);
}
else if (ask == 2) //按姓名查找
{
printf("Enter the name of the student\n");
scanf("%s", &N_name);
head = N_Delete(head, N_name);
}
}
else if (ask == 4) //添加数据
{
printf("If you want to add the student message before the student you choose please enter 1\n");
printf("If you want to add the student message after the student you choose please enter 2\n");
scanf("%d", &num);
printf("please enter the name 、Id and score of the new student\n");
scanf("%s%d%lf", &N_name, &N_Id, &N_score);
head = add(head, N_name, N_Id, N_score, num);
}
else if (ask == 5)
head = readin();
else if (ask == 6)
sort(head);
else if (ask == 7)
average(head);
else if (ask == 8)
find(head);
else
{
printf("Thank you to use!\n");
over(head); //释放所有空间
}
system("pause");
system("CLS");
showmenu();
return head;
}
//文件读入
List readin()
{
FILE * fp;
char fileDir[] = "D:\\tom and his firends\\development\\code\\c c++\\program\\学生管理系统\\message.txt";
List head, current, record;
char name[SIZE];
int Id; double score;
head = NULL;
fp = fopen(fileDir, "r");
if (fp == NULL) //判断文件是否存在
{
printf("fail to open the flie!\n");
exit(0);
}
while (~fscanf(fp, "%s", name)) //读入数据
{
current = (List)malloc(sizeof(struct Student));
if (head == NULL)
head = current;
else
record->next = current;
fscanf(fp, "%d %lf", &Id, &score);
strcpy(current->name, name);current->Id = Id;current->score = score;
current->next = NULL;
record = current;
}
fclose(fp);
return head;
}
//显示某个学生的数据
void find(List head)
{
int ask;char name[SIZE];int Id;List current;
current = head;
if (current == NULL)
{
printf("The list is empty\n");
return;
}
printf("If you want to find the student by Id,please enter 1\n");
printf("If you want to find the student by name,please enter 2\n");
scanf("%d", &ask);
if (ask == 1)
{
printf("Please enter the Id of the student you want to find\n");
scanf("%d", &Id);
while (current->next != NULL && current->Id != Id)
current = current->next;
if (current->Id == Id)
{
printf("----------------------------------\n");
printf("ID score name\n");
printf("----------------------------------\n");
printf("%d %.2lf %s \n", current->Id, current->score, current->name);
printf("----------------------------------\n");
}
else
printf("404 no find\n");
}
else if (ask == 2)
{
printf("Please enter the name of the student you want to find\n");
scanf("%s", name);
while (current->next != NULL && strcmp(current->name, name) != 0)
current = current->next;
if (strcmp(current->name, name) == 0)
{
printf("----------------------------------\n");
printf("ID score name\n");
printf("----------------------------------\n");
printf("%d %.2lf %s \n", current->Id, current->score, current->name);
printf("----------------------------------\n");
}
else
printf("404 no find\n");
}
}
//显示平均成绩、人数、总和分数
void average(List head)
{
List current;
float total = 0;int Tperson = 0;float average = 0;
current = head;
if (current == NULL)
{
printf("the list is empty!\n");
return ;
}
while (current)
{
total += current->score;Tperson++;
current = current->next; //向后遍历;
}
if (Tperson != 0) average = total / Tperson;
printf("the total score is %.2f,the total person is %d,the average socre is %.2f\n", total, Tperson, average);
}
//排序
void sort(List head)
{
int ask;List current, record;int n, i;char name[SIZE];int Id;double score;
struct Student change;
current = head;
if (current == NULL) //判断当前表是否为空
{
printf("The list is empty!\n");
return;
}
for (;current;current = current->next) n++; //记录当前有多少人,即进行多少次循环
current = head;
printf("If you want to sort the student message by score,please enter 1\n");
printf("If you want to sort the student message by Id ,please enter 2\n");
scanf("%d", &ask);
if (ask == 1)
{
for (i = 0;i < n;i++)
{
while (current->next)
{
record = current->next;
if (current->score < record->score)
{
strcpy(name, current->name); Id = current->Id;score = current->score;
strcpy(current->name, record->name), current->Id = record->Id;current->score = record->score;
strcpy(record->name, name), record->Id = Id;record->score = score;
}
current = current->next;
}
current = head;
}
}
else
{
current = head;
for (i = 0;i < n;i++)
{
while (current->next)
{
record = current->next;
if (current->Id > record->Id)
{
strcpy(name, current->name); Id = current->Id;score = current->score;
strcpy(current->name, record->name), current->Id = record->Id;current->score = record->score;
strcpy(record->name, name), record->Id = Id;record->score = score;
}
current = current->next;
}
current = head;
}
}
}