本人刚上大二,没有学过面相对象编程,代码简陋,可扩展性差,不喜勿喷
特别是在排序的时候,因为C语言没有多态,所以写了许多相似的代码。如果有什么方法可以减少这些代码量,还请各位在下面留言。
/*
系统需求开发
1.对用户的有效信息进行输入和排序
2.实现统计用户成绩的总分和平均分
3.能够查看单个用户的各个成绩
模块分析和数据结构
typedef struct student
{
char name[];
char num[];
int Cgrade;
int Mgrade;
int Egrade;
int total;
float ave;
int rank;
};
typedef struct node
{
struct student data;
struct node *next;
}Node,Link;
}
*/
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<windows.h>
#pragma warning(disable:4996)
#define HEADER1 "|---------------------------STUDENT------------------------------------------------ |\n"
#define HEADER2 "| number | name | Comp | Math | Eng | Sum | ave | rank |\n"
#define HEADER3 "|--------|------------------------------|------|------|------|------|--------|------|\n"
#define FORMAT "| %-4d |%-30s| %-4d | %-4d | %-4d | %-4d | %-6.2f | %-4d |\n"
#define Ending "|-----------------------------END-------------------------------------------------- |\n"
#define Choose "|--------------------------------------------------|\n"
#define ChoEnd "|--------------------------------------------------|\n"
typedef struct student
{
char name[20];
int num;
int Cgrade;
int Mgrade;
int Egrade;
int total;
float ave;
int rank;
}student;
typedef struct node
{
struct student data;
struct node *next;
}Node, *Link;
#define DATA p->data.num,p->data.name,p->data.Cgrade,p->data.Mgrade,p->data.Egrade,p->data.total,p->data.ave,p->data.rank
void header()
{
printf(HEADER1);
printf(HEADER2);
printf(HEADER3);
}
void printData(Node*pp)
{
node*p;
p = pp;
printf(FORMAT,DATA);
}
void gotoxy(int x, int y)/*在控制台输出坐标位置*/
{
COORD coord; //定义一个坐标结构变量
HANDLE hscr; //定义一个句柄
coord.X = x; //给坐标赋值
coord.Y = y;
hscr = GetStdHandle(STD_OUTPUT_HANDLE); //获得标准输出句柄(就是显示器)
SetConsoleCursorPosition(hscr, coord); //设置控制台光标的到指定坐标
}
void menu()
{
system("cls");
//textcolor(10);
printf("------------------------------学生管理系统------------------------------\n");
printf("----------------------------------菜单----------------------------------\n");
printf("\t\t|0:退出\t\t|1:输入\n\t\t|2:删除\t\t|3:寻找\n\t\t|4:修改\t\t|5:插入\n\t\t|6:总数\t\t|7:排序\n\t\t|8:储存\t\t|9:展示\n");
printf("------------------------------------------------------------------------\n");
}
int JudgeNum(Link l,int num)/*判断学号是否重复*/
{
Node*s = l;
int count=1;//如果有重复的学号就返回0 没有重复的就返回1
while (s != NULL)/*判断是否有重复的学号*/
{
if (s->data.num == num)
{
printf("该学号已经存在,请重新输入学号\n");
count = 0;//标记学号重复
printf(ChoEnd);
Sleep(200);
system("cls");
break;
}
s = s->next;
}
return count;
}
void Add(Link l)
{//添加用户信息
int num;//存储学号信息 当num=0时退出add系统
int count=1;
Node* r,*s,*p;
r = l;
while (r->next != NULL)
r = r->next;
s = l;
printf("可以多次输入\n\n");
Sleep(200);
while (1)
{
system("cls");
printf(Choose);
printf("0:退出\n请输入学号:");
scanf("%d",&num);
if (num == 0)
break;
count = JudgeNum(l, num);//判断学号是否重复 如果重复返回0 不重复返回1
if (count)
{
p = (Node*)malloc(sizeof(Node));
p->data.num = num;
printf("名字:\n");
scanf("%s", &p->data.name);
printf("C语言:\n");
scanf("%d", &p->data.Cgrade);
printf("英语:\n");
scanf("%d", &p->data.Egrade);
printf("数学:\n");
scanf("%d", &p->data.Mgrade);
printf(ChoEnd);
system("cls");
printf("\t\t以下信息已经添加完毕\n\n");
p->data.total = p->data.Mgrade + p->data.Cgrade + p->data.Egrade;//得到总分
p->data.ave = (float)p->data.total / 3;//得到平均分
p->data.rank = 0;
header();
printData(p);
printf(Ending);
p->next = NULL;
r->next = p;
r = p;
system("pause");
system("cls");
}
count = 1;
}
}
void Del(Link l)
{
int select;
int num;
int count1 = 0;/*用来计算是否找到这个学号*/
int count = 0;/*用于计算同名的人数*/
char name[30];/*ch用来判断是否要删除名字*/
Node*p = l;
while (1)
{
printf(Choose);
printf(" 选择根据什么进行删除\n");
printf(" 1:根据学号进行删除\n 2:根据名字删除\n 0:退出\n");
scanf("%d", &select);
printf(ChoEnd);
if (select == 1)
{
printf("请输入学号\n");
scanf("%d",&num);
while (p->next!= NULL)
{
if (p->next->data.num == num)
{
count1++;
if (p->next->next != NULL)
{//如果要删除的数据不是最后一个,那么就把要删除的数据的前项与后项相互连接
p->next = p->next->next;
printf("学号为%d的信息已经删除\n", num);
break;
}
else
{//如果是最后一个 那么就把前项的next设置为NULL
p->next = NULL;
printf("学号为%d的信息已经删除\n", num);
break;
}
}
header();
printData(p);
p = p->next;
}
if (count1 == 0)
printf("没有找到学号为%d的人的信息\n",num);
system("pause");
system("cls");
}
else if (select == 2)
{
printf("请输入需要删除的人名\n");
scanf("%s",name);
while (p->next!=NULL)
{
if (strcmp(name, p->next->data.name) == 0)
{
count++;
header();
printData(p->next);
printf(Ending);
printf("\t确定要删除吗?\n\t1:确定删除\t任意键:不删除\n");
scanf("%d",&select);
if (select == 1)/*确认是否要删除*/
{
if (p->next->next != NULL)
{
p->next = p->next->next;
printf("删除成功\n");
break;
}
else
{
p->next = NULL;
printf("删除成功\n");
break;
}
}
system("pause");
}
p = p->next;
}
if (count == 0)
printf("没有找到%s的信息\n", name);
}
else if (select == 0)
break;
else
printf("系统无法识别指令 请重新输入\n");
system("cls");
}
}
void OutAll(Link l)/*输出所有的资料*/
{
Node*r;
r = l->next;
header();
while (r != NULL)
{
printData(r);
r = r->next;
}
printf(Ending);
system("pause");
}
void Find(Link l)
{
Node*s;
int select,num;
char name[30];
while (1)
{
s = l;
printf(Choose);
printf("1:学号查找\t2:姓名查找\t0:退出查找\n");
printf(ChoEnd);
scanf("%d",&select);
system("cls");
if (select == 0)
break;
else if (select == 1)
{
printf(Choose);
printf("请输入要查询的学号\n\n");
printf(ChoEnd);
scanf("%d",&num);
while (s)
{
if (s->data.num == num)
{
header();
printData(s);
printf(Ending);
system("pause");
}
s = s->next;
}
}
else if (select == 2)
{
printf(Choose);
printf("请输入要查询的姓名\n\n");
printf(ChoEnd);
scanf("%s", name);
while (s)
{
if (strcmp(name,s->data.name)==0)
{
header();
printData(s);
printf(Ending);
system("pause");
}
s = s->next;
}
}
else
{
printf("没有这个系统命令\n\n");
}
system("cls");
}
}
void Modify(Link l)
{
Node*p;
int select, num,select1,count;
char name[30];
while (1)
{
p = l;
printf(Choose);
printf("1:学号修改\t2:姓名修改\t0:退出修改\n");
printf(ChoEnd);
scanf("%d", &select);
system("cls");
if (select == 0)
break;
else if (select == 1)
{
printf(Choose);
printf("请输入要修改的学号的信息\n\n");
printf(ChoEnd);
scanf("%d", &num);
while (p)
{
if (p->data.num == num)
{
header();
printData(p);
printf(Ending);
printf("确定要修改这个数据吗?\n\n1:确认\t2:取消\t0:退出\n");
scanf("%d",&select1);
if (select1 == 0)
break;
if (select1 == 1)
{
printf("学号:\n");
scanf("%d", &p->data.num);
count = JudgeNum(l, p->data.num);
if (count) {
printf("名字:\n");
scanf("%s", &p->data.name);
printf("C语言:\n");
scanf("%d", &p->data.Cgrade);
printf("英语:\n");
scanf("%d", &p->data.Egrade);
printf("数学:\n");
scanf("%d", &p->data.Mgrade);
printf(ChoEnd);
system("cls");
printf(" 以下信息已经添加完毕\n\n");
p->data.total = p->data.Mgrade + p->data.Cgrade + p->data.Egrade;
p->data.ave = (float)p->data.total / 3;
p->data.rank = 0;
header();
printData(p);
printf(Ending);
}
}
else
continue;
system("pause");
}
p = p->next;
}
}
else if (select == 2)/*修改姓名*/
{
printf(Choose);
printf("请输入要修改的姓名\n\n");
printf(ChoEnd);
scanf("%s", name);
while (p)
{
if (strcmp(name, p->data.name) == 0)
{
header();
printData(p);
printf(Ending);
printf(" 确定要修改这个数据吗?\n\n1:确认\t2:取消\t0:退出\n");
scanf("%d", &select1);
if (select1 == 0)
break;
if (select1 == 1)
{
printf("学号:\n");
scanf("%d", &p->data.num);
count = JudgeNum(l, p->data.num);
if (count)
{
printf("名字:\n");
scanf("%s", &p->data.name);
printf("C语言:\n");
scanf("%d", &p->data.Cgrade);
printf("英语:\n");
scanf("%d", &p->data.Egrade);
printf("数学:\n");
scanf("%d", &p->data.Mgrade);
printf(ChoEnd);
system("cls");
printf("\t以下信息已经添加完毕\n\n");
p->data.total = p->data.Mgrade + p->data.Cgrade + p->data.Egrade;
p->data.ave = (float)p->data.total / 3;
p->data.rank = 0;
header();
printData(p);
printf(Ending);
}
}/*修改信息*/
else
{
p = p->next;
continue;
}
system("pause");
}
p = p->next;
}
}
else
{
printf("没有这个系统命令\n\n");
}
system("cls");
}
}
void Insert(Link l)
{
}
int Sum(Link l)
{
Node*s = l;
int count = 0;
while (s)
{
count++;
s = s->next;
}
return count - 1;
}
void ShowRank(Link l)
{
Link s = l->next;
int i = 1;
while (s != NULL)
{
s->data.rank = i;
i++;
s = s->next;
}
}
void selectSortByNum(Link l)
{
if ((l->next == NULL) || (l->next->next == NULL))
{
return;
}
node * head, *prep1, *p1, *prep2, *p2, *premax, *max, *temp;
head = l;
for (prep1 = head, p1 = prep1->next; p1->next != NULL; prep1 = prep1->next, p1 = prep1->next)
{
//保存最大节点
premax = prep1;
max = p1;
for (prep2 = p1, p2 = prep2->next; p2 != NULL; prep2 = prep2->next, p2 = prep2->next)
{
if (max->data.num < p2->data.num)
{
premax = prep2;
max = p2;
}
}
if (p1 != max)
{
//一定要注意这个情况
if (p1->next == max)
{
temp = max->next;
prep1->next = max;
max->next = p1;
p1->next = temp;
}
else {
temp = max->next;
prep1->next = max;
max->next = p1->next;
premax->next = p1;
p1->next = temp;
}
}
}
ShowRank(l);
printf("信息排序成功\n");
system("pause");
}
void selectSortBySum(Link l)
{
if ((l->next == NULL) || (l->next->next == NULL))
{
return;
}
node * head, *prep1, *p1, *prep2, *p2, *premax, *max, *temp;
head = l;
for (prep1 = head, p1 = prep1->next; p1->next != NULL; prep1 = prep1->next, p1 = prep1->next)
{
//保存最大节点
premax = prep1;
max = p1;
for (prep2 = p1, p2 = prep2->next; p2 != NULL; prep2 = prep2->next, p2 = prep2->next)
{
if (max->data.total < p2->data.total)
{
premax = prep2;
max = p2;
}
}
if (p1 != max)
{
//一定要注意这个情况
if (p1->next == max)
{
temp = max->next;
prep1->next = max;
max->next = p1;
p1->next = temp;
}
else {
temp = max->next;
prep1->next = max;
max->next = p1->next;
premax->next = p1;
p1->next = temp;
}
}
}
ShowRank(l);
printf("信息排序成功\n");
system("pause");
}
void selectSortByMath(Link l)
{
if ((l->next == NULL) || (l->next->next == NULL))
{
return;
}
node * head, *prep1, *p1, *prep2, *p2, *premax, *max, *temp;
head = l;
for (prep1 = head, p1 = prep1->next; p1->next != NULL; prep1 = prep1->next, p1 = prep1->next)
{
//保存最大节点
premax = prep1;
max = p1;
for (prep2 = p1, p2 = prep2->next; p2 != NULL; prep2 = prep2->next, p2 = prep2->next)
{
if (max->data.Mgrade < p2->data.Mgrade)
{
premax = prep2;
max = p2;
}
}
if (p1 != max)
{
//一定要注意这个情况
if (p1->next == max)
{
temp = max->next;
prep1->next = max;
max->next = p1;
p1->next = temp;
}
else {
temp = max->next;
prep1->next = max;
max->next = p1->next;
premax->next = p1;
p1->next = temp;
}
}
}
ShowRank(l);
printf("信息排序成功\n");
system("pause");
}
void selectSortByComp(Link l)
{
if ((l->next == NULL) || (l->next->next == NULL))
{
return;
}
node * head, *prep1, *p1, *prep2, *p2, *premax, *max, *temp;
head = l;
for (prep1 = head, p1 = prep1->next; p1->next != NULL; prep1 = prep1->next, p1 = prep1->next)
{
//保存最大节点
premax = prep1;
max = p1;
for (prep2 = p1, p2 = prep2->next; p2 != NULL; prep2 = prep2->next, p2 = prep2->next)
{
if (max->data.Cgrade < p2->data.Cgrade)
{
premax = prep2;
max = p2;
}
}
if (p1 != max)
{
//一定要注意这个情况
if (p1->next == max)
{
temp = max->next;
prep1->next = max;
max->next = p1;
p1->next = temp;
}
else {
temp = max->next;
prep1->next = max;
max->next = p1->next;
premax->next = p1;
p1->next = temp;
}
}
}
ShowRank(l);
printf("信息排序成功\n");
system("pause");
}
void selectSortByEnglish(Link l)
{
if ((l->next == NULL) || (l->next->next == NULL))
{
return;
}
node * head, *prep1, *p1, *prep2, *p2, *premax, *max, *temp;
head = l;
for (prep1 = head, p1 = prep1->next; p1->next != NULL; prep1 = prep1->next, p1 = prep1->next)
{
//保存最大节点
premax = prep1;
max = p1;
for (prep2 = p1, p2 = prep2->next; p2 != NULL; prep2 = prep2->next, p2 = prep2->next)
{
if (max->data.Egrade < p2->data.Egrade)
{
premax = prep2;
max = p2;
}
}
if (p1 != max)
{
//一定要注意这个情况
if (p1->next == max)
{
temp = max->next;
prep1->next = max;
max->next = p1;
p1->next = temp;
}
else {
temp = max->next;
prep1->next = max;
max->next = p1->next;
premax->next = p1;
p1->next = temp;
}
}
}
ShowRank(l);
printf("信息排序成功\n");
system("pause");
}
void selectSort(Link l)
{
int choose;
printf("1:学号 2:总分\n3:数学 4:C语言\n5:英语 0:退出\n");
scanf("%d", &choose);
switch (choose)
{
case 0:break;
case 1:selectSortByNum(l); break;
case 2:selectSortBySum(l); break;
case 3:selectSortByMath(l); break;
case 4:selectSortByComp(l); break;
case 5:selectSortByEnglish(l); break;
default:
printf("没有这个选项\n");
break;
}
}
void Save(Link l)
{
FILE*fp;
Link p;
p = l->next;
fp = fopen("E:\\student.txt", "w");
if (fp)
{
while (p)
{
if(fwrite(p,sizeof(Node),1,fp)==1)
p = p->next;
}
printf("写入成功\n\n");
fclose(fp);
}
else
printf("文件打开失败,请重试\n\n");
system("pause");
}
void TipSave(Link l)
{/*提示是否要保存修改 当数据没有处理过的时候不提示
如果选择储存则在储存后退出这个系统*/
char t;
int s = 1000;/*用于控制在几秒后返回主界面*/
printf("你还没有保存数据 是否要保存数据?\n\n");
printf(" 按Y保存 按N不保存\n\n" );
getchar();
scanf("%c",&t);
if (t == 'Y' || t == 'y')
{
Save(l);
free(l);
exit(0);
printf("感谢您的使用\n");
}
else if (t == 'N' || t == 'n')
{
exit(0);
free(l);
printf("感谢您的使用\n");
}
else
{
printf("未识别您输入的指令\n\n系统将在%d秒后返回主界面", s / 1000);
Sleep(s);
}
}
int main()
{
Link l;
FILE*fp;
node*p, *r;
int select,count=0,sum;
int save = 1;/*显示是否储存 如果储存 save为1*/
l = (Link)malloc(sizeof(Node));
if (l == NULL)
{
printf("系统打开失败\n\n");
return 0;
}
l->next = NULL;
r = l;
fp = fopen("E:\\student.txt", "a+");
while (!feof(fp))
{
p = (Node*)malloc(sizeof(Node));
if (!p)
{
printf("系统打开文件失败\n\n");
continue;
}
else
{
if(fread(p, sizeof(Node), 1, fp)==1)
{
p->next = NULL;
r->next = p;
r = p;
count++;
}
}
}
fclose(fp);
printf("--------------------%d条记录读取完成------------------------\n\n",count);
system("pause");
while (true)
{
menu();
printf("请输入你的选择\n");
scanf("%d",&select);
system("cls");
if (select == 0)
{
if(save==0)
TipSave(l);
break;
}
else if (select == 8)
{
Save(l);
save = 1;
free(l);
break;
}
else
{
switch (select)
{
case 1:Add(l); save = 0; break;
case 2:Del(l); save = 0; break;
case 3:Find(l); save = 0; break;
case 4:Modify(l); save = 0; break;
case 6:sum = Sum(l); printf("有%d条记录", sum); system("pause"); break;
case 7:selectSort(l); break;
case 9:OutAll(l); break;
default:printf("没有这条的存在指令\n\n");
break;
}
}
}
return 0;
}