为了迎接即将到来的数据结构实训,我终于抽时间提前把学生成绩信息管理系统给敲完了,本来是想用纯c++来写的,但是文件操作那一块c++我有点没搞懂就用了c的文件操作,我也不知道使用啥写的了,有c++也有c,因为c++兼容c,所以运行没啥子问题,就是没那么规范。
#define _CRT_SECURE_NO_WARNINGS //vs宏定义
#include<iostream>
#include<stdio.h>
#include<malloc.h>
#include<string.h>
using namespace std;
struct student {
char name[10], sex[3], student_id[20], id_number[20];
int age, math, english, politics, sum;
};
typedef struct list {
student data;
struct list* next;
}*listd;
listd headlist(); //初始化链表,创建头结点
listd headlist() {
listd head = (listd)malloc(sizeof(list));
head->next = NULL;
return head;
}
listd newlist(student x); //创建新节点
listd newlist(student x) {
listd p = (listd)malloc(sizeof(list));
p->data = x;
p->next = NULL;
return p;
}
void intolist(listd head, student x); //插入链表结点
void intolist(listd head, student x) {
listd s = newlist(x);
s->next = head->next;
head->next = s;
}
listd checklist(listd head, char* x); //查找结点
listd checklist(listd head, char* x) {
listd p = head->next;
while (p) {
if (!strcmp(p->data.name, x) || !strcmp(p->data.student_id, x))
return p;
p = p->next;
}
return NULL;
}
bool dellist(listd head, char* x); //删除结点
bool dellist(listd head, char* x) {
listd p, s;
p = head;
s = head->next;
if (s == NULL) {
return false;
}
while (1) {
if (!strcmp(s->data.name, x) || !strcmp(s->data.student_id, x)) {
break;
}
p = s;
s = s->next;
if (s == NULL) {
return false;
}
}
p->next = s->next;
free(s);
return true;
}
void reviselist(listd head, int a, char* x); //修改内容
void reviselist(listd head, int a, char* x) {
char name[10], sex[3], student_id[20], id_number[20];
int age, len, i, math, english, politics;
listd p = head->next;
while (p) {
if (!strcmp(p->data.name, x))
break;
p = p->next;
}
switch (a) {
case 1:
cout << "请输入新的姓名:" << endl;
cin >> name;
len = sizeof(name) / sizeof(char);
for (i = 0; i < len; i++)
p->data.name[i] = name[i];
break;
case 2:
cout << "请输入新的性别:" << endl;
cin >> sex;
len = sizeof(sex) / sizeof(char);
for (i = 0; i < len; i++)
p->data.sex[i] = sex[i];
break;
case 3:
cout << "请输入新的年龄:" << endl;
cin >> age;
p->data.age = age;
break;
case 4:
cout << "请输入新的学号:" << endl;
cin >> student_id;
len = sizeof(student_id) / sizeof(char);
for (i = 0; i < len; i++)
p->data.student_id[i] = student_id[i];
break;
case 5:
cout << "请输入新的身份证号:" << endl;
cin >> id_number;
len = sizeof(id_number) / sizeof(char);
for (i = 0; i < len; i++)
p->data.id_number[i] = id_number[i];
break;
case 6:
cout << "请输入新的数学成绩:" << endl;
cin >> math;
p->data.math = math;
p->data.sum = p->data.math + p->data.english + p->data.politics;
break;
case 7:
cout << "请输入新的英语成绩:" << endl;
cin >> english;
p->data.english = english;
p->data.sum = p->data.math + p->data.english + p->data.politics;
break;
case 8:
cout << "请输入新的政治成绩:" << endl;
cin >> politics;
p->data.politics = politics;
p->data.sum = p->data.math + p->data.english + p->data.politics;
break;
}
}
void statistics(listd head, int b); //查看单科的平均分,最高分,最低分
void statistics(listd head, int b) {
int l = 0, max = -1, min = 999;
float sum = 0;
listd p = head;
switch (b) {
case 1:
for (p = p->next; p != NULL; p = p->next) {
if (p->data.math > max)
max = p->data.math;
if (p->data.math < min)
min = p->data.math;
sum += p->data.math;
l++;
}
cout << "数学成绩信息~\n最高分\t最低分\t平均分" << endl;
printf("%d\t%d\t%.2f", max, min, sum / l);
break;
case 2:
for (p = p->next; p != NULL; p = p->next) {
if (p->data.english > max)
max = p->data.english;
if (p->data.english < min)
min = p->data.english;
sum += p->data.english;
l++;
}
cout << "英语成绩信息~\n最高分\t最低分\t平均分" << endl;
printf("%d\t%d\t%.2f", max, min, sum / l);
break;
case 3:
for (p = p->next; p != NULL; p = p->next) {
if (p->data.politics > max)
max = p->data.politics;
if (p->data.politics < min)
min = p->data.politics;
sum += p->data.politics;
l++;
}
cout << "政治成绩信息~\n最高分\t最低分\t平均分" << endl;
printf("%d\t%d\t%.2f", max, min, sum / l);
break;
}
}
void rise_sum(listd head); //按总分交换升序排序
void rise_sum(listd head) {
listd p = head;
listd s, q;
for (p = p->next; p->next != NULL; p = p->next)
for (s = p->next; s != NULL; s = s->next) {
if (p->data.sum > s->data.sum)
{
q = newlist(p->data);
p->data = s->data;
s->data = q->data;
free(q);
}
}
}
void add_sum(listd head);//按总分插入排序
void add_sum(listd head) {
listd p,s;
student x;
student next[100];
int i = 0,c;
for (p = head->next; p->next != NULL; p = p->next) {
x = p->data;
for (s = p->next; s != NULL; s = s->next) {
if (s->data.sum < x.sum)
{
intolist(s, x);
break;
}
}
next[i++] = x;
if(s==NULL)
intolist(head, x);
}
for (c = 0; c < i; c++)
dellist(head,next[c].name);
}
void stack(student a[], int k, int len);//调整堆
void stack(student a[], int k, int len) {
int i;
student s;
for ( i = 2 * k; i <=len; i *= 2) {
if (i<len&&a[i].sum > a[i+1].sum)
{
i++;
}
if (a[k].sum<=a[i].sum)
{
break;
}
else
{
s=a[k];
a[k]= a[i];
a[i] = s;
}
}
}
void stack1(student a[], int len);//从最后一个的双亲结点开始反复调整堆
void stack1(student a[], int len) {
for (int i = len/2; i >0; i--)
{
stack(a, i, len);
}
}
void stacksum(student a[], int len);//堆顶元素依次输出
void stacksum(student a[], int len) {
int i;
student s;
stack1(a, len);
cout << "\t姓名\t性别\t年龄\t学号\t\t身份证号\t\t数学\t英语\t政治\t总成绩\t" << endl;
for (i = len ; i > 0; i--) {
printf("\t%s\t%s\t%d\t%s\t%s\t%d\t%d\t%d\t%d\t\n", a[1].name, a[1].sex,
a[1].age, a[1].student_id, a[1].id_number, a[1].math, a[1].english, a[1].politics, a[1].sum);
s = a[1];
a[1] = a[i];
a[i] = s;
stack(a, i - 1);
}
}
void readf(listd head, const char* name); //文件的读操作
void readf(listd head, const char* name) {
FILE* fp;
student x;
fp = fopen(name, "r");
if (fp == NULL) {
fp = fopen(name, "w+");
}
while (fscanf(fp, "\t%s\t%s\t%d\t%s\t%s\t%d\t%d\t%d\t%d\t\n", x.name, x.sex,
&x.age, x.student_id, x.id_number, &x.math, &x.english, &x.politics, &x.sum) != EOF) {
intolist(head, x);
}
fclose(fp);
}
void writef(listd head, const char* name); //文件写操作
void writef(listd head, const char* name) {
FILE* fp;
listd p = head->next;
fp = fopen(name, "w");
while (p) {
fprintf(fp, "\t%s\t%s\t%d\t%s\t%s\t%d\t%d\t%d\t%d\t\n", p->data.name, p->data.sex,
p->data.age, p->data.student_id, p->data.id_number, p->data.math, p->data.english, p->data.politics, p->data.sum);
p = p->next;
}
}
void copylist(listd head, const list root); //拷贝链表操作
void copylist(listd head, const list root)
{
listd p ;
for (p = root.next; p != NULL; p = p->next) {
intolist(head, p->data);
}
}
void printlist(listd head);//打印链表
void printlist(listd head) {
listd p = head->next;
while (p) {
printf("\t%s\t%s\t%d\t%s\t%s\t%d\t%d\t%d\t%d\t\n", p->data.name, p->data.sex,
p->data.age, p->data.student_id, p->data.id_number, p->data.math, p->data.english, p->data.politics, p->data.sum);
p = p->next;
}
}
int structure(int a, listd head); //后台交互结构
int structure(int a, listd head) {
student x,c[100];
listd p,s;
s = headlist();
int b;
switch (a) {
case 1:
cout << "请按顺序分别输入~" << endl << "姓名 性别 年龄 学号 身份证号 数学成绩 英语成绩 政治成绩:" << endl;
scanf("%s%s%d%s%s%d%d%d", &x.name, &x.sex, &x.age, &x.student_id, &x.id_number, &x.math, &x.english, &x.politics);
x.sum = x.math + x.english + x.politics;
intolist(head, x);
break;
case 2:
cout << "请输入需要查找的姓名或学号:" << endl;
cin >> x.name;
p = checklist(head, x.name);
if (p == NULL)
cout << "查找失败" << endl;
else {
cout << "\t姓名\t性别\t年龄\t学号\t\t身份证号\t\t数学\t英语\t政治\t总成绩\t" << endl;
printf("\t%s\t%s\t%d\t%s\t%s\t%d\t%d\t%d\t%d\t\n", p->data.name, p->data.sex,
p->data.age, p->data.student_id, p->data.id_number, p->data.math, p->data.english, p->data.politics, p->data.sum);
} system("pause");
break;
case 3:
L:
cout << "请输入要删除的姓名或学号:" << endl;
cin >> x.name;
if (!dellist(head, x.name)) {
cout << "删除学生失败!" << endl;
cout << "输入1退回主菜单 输入任意“数字”则重新输入~" << endl;
cin >> b;
if (b == 1)
return 0;
else
goto L;
}
else
cout << "删除成功" << endl;
system("pause");
break;
case 4:
cout << "\t姓名\t性别\t年龄\t学号\t\t身份证号\t\t数学\t英语\t政治\t总成绩\t" << endl;
printlist(head);
cout << "请输入需要修改的姓名或学号:";
while (1) {
cin >> x.name;
p = checklist(head, x.name);
if (p == NULL)
cout << "修改内容不存在!!!" << endl;
else {
cout << "\t姓名\t性别\t年龄\t学号\t\t身份证号\t\t数学\t英语\t政治\t总成绩\t" << endl;
printf("\t%s\t%s\t%d\t%s\t%s\t%d\t%d\t%d\t%d\t\n", p->data.name, p->data.sex,
p->data.age, p->data.student_id, p->data.id_number, p->data.math, p->data.english, p->data.politics, p->data.sum);
break;
}
cout << "·输入1返回主菜单" << endl << "·输入任意数字重新输入" << endl;
cout << "~请输入:";
cin >> b;
if (b == 1)
return 0;
else
cout << "请输入需要修改的姓名或学号:";
}
cout << "请输入需要修改的属性编号:" << endl;
cout << "属性: 1.姓名 2.性别 3.年龄 4.学号 5.身份证号 6.数学成绩 7.英语成绩 8.政治成绩" << endl;
while (1) {
cin >> b;
if (b > 0 && b < 9)
break;
cout << "选择无效请重新输入:" << endl;
cout << "·输入1返回主菜单" << endl << "·输入任意数字重新输入" << endl;
cout << "~请输入:";
cin >> b;
if (b == 1)
return 0;
else
cout << "请输入需要修改的属性编号:" << endl;
cout << "属性: 1.姓名 2.性别 3.年龄 4.学号 5.身份证号 6.数学成绩 7.英语成绩 8.政治成绩" << endl;
}
reviselist(head, b, x.name);
cout << "修改成功" << endl;
cout << "\t姓名\t性别\t年龄\t学号\t\t身份证号\t\t数学\t英语\t政治\t总成绩\t" << endl;
printf("\t%s\t%s\t%d\t%s\t%s\t%d\t%d\t%d\t%d\t\n", p->data.name, p->data.sex,
p->data.age, p->data.student_id, p->data.id_number, p->data.math, p->data.english, p->data.politics, p->data.sum);
system("pause");
break;
case 5:
cout << "请输入需要查询的单科成绩编号:" << endl;
cout << "1.数学 2.英语 3.政治" << endl;
while (1) {
cin >> b;
if (b > 0 && b < 4)
break;
cout << "选择无效请重新输入:" << endl;
cout << "·输入1返回主菜单" << endl << "·输入任意数字重新输入" << endl;
cout << "~请输入:";
cin >> b;
if (b == 1)
return 0;
else
cout << "请输入需要查询的单科成绩编号:" << endl << "1.数学 2.英语 3.政治" << endl;
}
statistics(head, b);
cout << endl;
system("pause");
break;
case 6:
cout << "\t姓名\t性别\t年龄\t学号\t\t身份证号\t\t数学\t英语\t政治\t总成绩\t" << endl;
printlist(head);
system("pause");
break;
case 7:
copylist(s, *head);
cout << "\t姓名\t性别\t年龄\t学号\t\t身份证号\t\t数学\t英语\t政治\t总成绩\t" << endl;
printlist(head);
cout << "请输入排序方式~"<<endl;
S:
cout << "1.交换排序\t2.插入排序\t3.堆排序" << endl;
cin >> b;
if (b<1||b>3)
{
cout << "请输入正确的编号:"<<endl;
goto S;
}
switch (b)
{
case 1:
cout << "排序已经完成~" << endl;
cout << "\t姓名\t性别\t年龄\t学号\t\t身份证号\t\t数学\t英语\t政治\t总成绩\t" << endl;
rise_sum(s);
printlist(s);
break;
case 2:
cout << "排序已经完成~" << endl;
cout << "\t姓名\t性别\t年龄\t学号\t\t身份证号\t\t数学\t英语\t政治\t总成绩\t" << endl;
add_sum(s);
printlist(s);
break;
case 3:
listd s;
int l;
w:
cout <<endl<< "请输入合理的个数~" << endl;
cout << "请输入排序的个数:" ;
cin >> b;
l = 0;
for (s = head->next; s != NULL; s = s->next) {
l++;
}
if (!(b > 0 && b <= l)) {
goto w;
}
listd p = head->next;
for (int i = 1; i <=b; i++) {
c[i] = p->data;
p = p->next;
}
cout << "排序已经完成~" << endl;
stacksum(c, b);
break;
}
system("pause");
break;
case 8:
writef(head, "student.txt");
cout << "正在正常退出!!!";
exit(0);
break;
} return 0;
}
void interface(); //用户交互界面
void interface() {
int a;
listd head = headlist();
readf(head, "student.txt");
while (1) {
cout << "================学生信息管理系统====================" << endl;
cout << endl;
cout << "\t\t1.添加学生信息" << endl;
cout << "\t\t2.查找学生信息" << endl;
cout << "\t\t3.删除学生信息" << endl;
cout << "\t\t4.修改学生信息" << endl;
cout << "\t\t5.查看单科成绩信息" << endl;
cout << "\t\t6.查看总信息" << endl;
cout << "\t\t7.对总分进行升序排序" << endl;
cout << "\t\t8.退出系统" << endl;
cout << "\t\t\t\t所有者:Geek_S" << endl << endl;
cout << "\t\t\t\t请正常退出系统" << endl;
cout << "\t\t\t\t否则无法保存数据!!" << endl;
cout << "=====================================================" << endl;
cout << "请输入需要执行的功能编号:";
while (1) {
cin >> a;
if (a > 0 && a < 9)
break;
cout << "输入无效请重新输入:" << endl;
}
structure(a, head);
system("cls");
}
}
int main() {
interface();
system("pause");
return 0;
}
//其实一个真正好的管理系统是需要不断完善的,功能可以随意加
//只要你想得到,都可以添加进去
内容并不是很难,虽然看起来代码挺多的但是难点并不是很多,和那些变态的算法题比起来写一个交互式系统并不是很烧脑的事情,里面用到的算法也是很简单的,就是一些基本的增删改查以及排序的操作,唯一的难点恐怕就只有堆排序那块地方了,还有链表的插入排序的时候造成了一系列的访问权限冲突的错误,最后不得已只能使用先插入后删除的方法了。