学生管理系统
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
typedef struct student/*定义学生信息结构体*/
{
char num[10];
char name[15];
int cgrade;
int mgrade;
int egrade;
int total;
float ave;
int mingci;
};
typedef struct node
{
struct student date;//数据域
struct node *next;//指针域
}Node,*Link;//Node代表node型变量,*Link代表node型指针
//光标定位
void gotoxy(int x,int y){
COORD c;
c.X=x-1;
c.Y=y-1;
SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c);
}
void menu();//菜单函数
void display(Link l);//输出记录函数
void printheader();//输出表格开头
void printdate(Node *pp);//输出表格内容
Node *Locate(Link l,char findmess[],char nameornum[]);//定位指针函数
void stringinput(char *t,unsigned int lens,char *notice);//格式化字符输入
int numberinput(char *notice);//格式化数据输入
void Add(Link l);//增加记录
void Qur(Link l);//查询记录
void Del(Link l);//删除记录
void Modify(Link l);//更改学生记录
void Insert(Link l); //插入记录
void Tongji(Link l);//统计信息
void Sort(Link l);//排序
void Save(Link l);//保存
int saveflag=0;
//主函数
int main()
{
int j,n;
char mima[10]="123456";
char inputmima[10];
Link l;//定义一个指针指向链表
FILE *fp;
int select;//菜单的选择项
char ch;
int count=0;
Node *p,*r;
system("COLOR 3a");
l=(Node*)malloc(sizeof(Node));
l->next=NULL;
r=l;
fp=fopen("C:\\student.txt","ab+");//已可读写方式打开
while(!feof(fp))
{
p=(Node*)malloc(sizeof(Node));
if(fread(p,sizeof(Node),1,fp)==1)
{
p->next=NULL;
r->next=p;
r=p;
count++;
}
}
fclose(fp);//关闭文件
gotoxy(25,5);
printf("\n你共有三次机会输入密码以进入系统!\n\n");
for(int i = 3; i >= 1; --i)
{
printf("\t\t");
printf("\n\n请输入密码以进入系统: ");
scanf("%s", &inputmima);
if(strcmp(mima, inputmima) != 0)
{
printf("\n\n密码输入错误!你还有 %d 次机会!\n\n\n\n\n\n\n\n\n", i - 1);
++j;
system("PAUSE");
system("CLS");
}
else
break;
}
if(j == 3)
{
printf("程序即将退出!\n\n");
system("pause");
exit(1);
}
system("cls");
gotoxy(20,5);//移动光标
printf("欢 迎 使 用 学 生 成 绩 管 理 系 统");
gotoxy(25,8);
printf("系统信息:现有学生成绩 :%d 条.\n\n\n\n\n",count);
printf("\n\n请按enter键继续操作");
getchar();
while(1)
{
system("cls");
menu();
printf("\n 请选择选项 (0-9):");
scanf("%d",&select);
if(select==9)//安全退出,保证信息能被保存
{
if(saveflag==1)//全局变量,标志未保存
{
printf("\n 是否需要保存信息 ? (y/n):");
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
Save(l);
}
printf("\t\t\t感谢您的使用 !\n\n\n");
break;//退出
}
switch(select)
{
case 0:
Add(l);
break;
case 1:
Del(l);
break;
case 2:
Qur(l);
break;
case 3:
Modify(l);
break;
case 4:
Insert(l);
break;
case 5:
Tongji(l);
break;
case 6:
Sort(l);
break;
case 7:
Save(l);
break;
case 8:
system("cls");
display(l);
break;
default:
printf("\n\n\n\n 敬告:输入错误,请按enter键返回菜单!!!\n");;
break;
}
}
return 0;
}
//菜单函数
void menu()
{
system("cls");
gotoxy(15,5);
printf("学生成绩管理系统 \n");
gotoxy(10,8);
printf("------------菜单-----------\n");
gotoxy(10,9);
printf("| 0 增加记录 | 5 统计信息 |\n");
gotoxy(10,10);
printf("| 1 删除信息 | 6 记录排序 |\n");
gotoxy(10,11);
printf("| 2 查询信息 | 7 保存信息 |\n");
gotoxy(10,12);
printf("| 3 修改信息 | 8 打印记录 |\n");
gotoxy(10,13);
printf("| 4 插入记录 | 9 安全退出 |\n");
gotoxy(10,14);
printf("---------------------------\n");
}
//输出表格函数
void display(Link l)
{
Node *p;
p=l->next;
if(!p)
{
printf("\n\t\t\t没有学生信息!\n\n\n");
return;
}
printf("\n\n");
printheader();
while(p)
{
printdate(p);
p=p->next;
printf(" ---------------|--------------|---- |----|----|-------|-------|----|\n");
}
printf("\n\n\n请按enter键继续操作");
getchar();
}
//输出表格头部
void printheader()
{
printf(" ------------------------------------------------------------------\n");
printf(" | 学号 | 姓名 |c语言|数学|英语| 总分 |平均分 |名次|\n");
printf(" ---------------|--------------|---- |----|----|-------|-------|----|\n");
}
//输出表格内容函数
void printdate(Node *pp)
{
Node*p;
p=pp;
printf("|%-15s|%-14s|%5d|%3d |%3d | %5d |%5.2f |%3d |\n",p->date.num,p->date.name,p->date.egrade,p->date.mgrade,p->date.cgrade,p->date.total,p->date.ave,p->date.mingci);
}
Node *Locate(Link l,char findmess[],char nameornum[])
{
Node *r;
if(strcmp(nameornum,"num")==0)//根据学号查询
{
r=l->next;
while(r)
{
if(strcmp(r->date.num,findmess)==0)//查找findmess相同的学号
return r;
r=r->next;
}
}
else if(strcmp(nameornum,"name")==0)//根据姓名查询
{
r=l->next;
while(r)
{
if(strcmp(r->date.name,findmess)==0)
return r;
r=r->next;
}
}
return 0;
}
void stringinput(char *t,unsigned int lens,char *notice)
{
char n[255];
do
{
printf(notice);
scanf("%s",n);
if(strlen(n)>lens)
printf("\n\t\t\t输入太长 !\n\n");
}while(strlen(n)>lens);
strcpy(t,n);
}
int numberinput(char *notice)
{
int t=0;
do
{
printf(notice);
scanf("%d",&t);//输入分数
if(t>100||t<0)
printf("\n\n\t分数必须在100以内 !\n\n");
}while(t>100||t<0);//检查分数
return t;
}
//增加学生纪录
void Add(Link l)
{
Node *p,*r,*s;//临时的结构体指针变量
char ch,flag=0,num[10];
r=l;
s=l->next;
system("cls");
display(l);//显现出已有的学生信息
while(r->next!=NULL)
r=r->next;//移动指针到表未,准备添加记录
while(1)//循环输入
{
while(1)
{
stringinput(num,10,"请输入学号(输入'0'返回菜单):");
//格式化输入学号并检查
flag=0;//标志学号是否已存在
if(strcmp(num,"0")==0)//输入为零返回菜单
{
return;
}
s=l->next;
while(s)//查询该学号是否已存在
{
if(strcmp(s->date.num,num)==0)
{
flag=1;
break;
}
s=s->next;
}
if(flag==1)
{
printf("\n\n\t\t学号 %s 已存在,是否重新? (y/n):\n\n",num);
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
continue;//其作用为结束本次循环
//即跳出循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判定
else
return;
}
else
{
break;
}//退出循环,接着录入信息
}
p=(Node *)malloc(sizeof(Node));
if(!p)
{
printf("\n allocaye memory failure ");
return;
}
strcpy(p->date.num,num);
stringinput(p->date.name,15,"姓名:");
//输入名字,并检查在15个字符内
p->date.cgrade=numberinput("C语言成绩 [0-100]:");
//输入分数,并检查在0到100分内
p->date.mgrade=numberinput("数学 成绩 [0-100]:");
p->date.egrade=numberinput("英语 成绩 [0-100]:");
p->date.total=p->date.cgrade+p->date.mgrade+p->date.egrade;
p->date.ave=(float)(p->date.total/3);
p->date.mingci=0;
p->next=NULL;
r->next=p;
r=p;
saveflag=1;
}
return;
}
//按学号或姓名,查询学生记录
void Qur(Link l)
{
int select;
char searchinput[20];
Node *p;
system("cls");
if(!l->next)
{
printf("\n======> 没有学生信息 !\n");
printf("\n\n\n请按enter键继续操作");
getchar();
return ;
}
printf("\n\n\n\t\tl 通过学号查询 2 通过名字查询\n");
printf(" 请选择 [1,2]:");
scanf("%d",&select);
if(select==1)//按学号查询
{
stringinput(searchinput,10,"请输入所查询学生的学号 :");
p=Locate(l,searchinput,"num");
if(p)
{
printheader();
printdate(p);
printf(" ------------------------------------------------------------------\n");
printf("\n\n\n请按enter键继续操作");getchar();
}
else
{
printf("\n\n\t没有找到这名名学生 !\n");;
printf("\n\n\n请按enter键继续操作");
getchar();
}
}
else if(select==2)//按姓名查询
{
stringinput(searchinput,15,"请输入所查询学生的姓名 :");
p=Locate(l,searchinput,"name");
if(p)
{
printheader();
printf(" ------------------------------------------------------------------\n");
printdate(p);
printf("\n\n\n请按enter键继续操作");
getchar();
}
else
{
printf("\n\n\t没有找到这名名学生 !\n");;
printf("\n\n\n请按enter键继续操作");
getchar();
}
}
else
{
printf("\n\n\n\n 敬告:输入错误,请按enter键返回菜单!!!\n");;
printf("\n\n\n请按enter键继续操作");
}
}
//删除学生记录
void Del(Link l)
{
int sel;
Node *p,*r;
char findmess[20];
system("cls");
if(!l->next)
{
printf("\n\t\t\t没有学生记录!\n");
printf("\n\n\n请按enter键继续操作");
getchar();
return;
}
display(l);
printf("\n \t 1 通过学号删除 2 通过姓名删除\n");fflush(stdin);
printf(" 请选择 [1,2]:");
scanf("%d",&sel);
if(sel==1)
{
stringinput(findmess,10,"请输入学号 :");
p=Locate(l,findmess,"num");//通过学号并找到该结构体
if(p)
{
r=l;
while(r->next!=p)//
r=r->next;
r->next=p->next;//删除P所指向的结构体
free(p);//释放内存
printf("\n\t\t\t删除成功 !\n\n\n");fflush(stdin);
saveflag=1;//全局变量,标志链表未保存
}
else
printf("\n\n\t没有找到这名名学生 !\n");;
printf("\n\n\n请按enter键继续操作");
getchar();
}
else if(sel==2)
{
stringinput(findmess,15,"请输入姓名 ");
p=Locate(l,findmess,"name");//按姓名查找
if(p)
{
r=l;
while(r->next!=p)
r=r->next;
r->next=p->next;
free(p);
printf("\n\t\t\t删除成功!\n\n\n");fflush(stdin);
saveflag=1;
}
else
printf("\n\n\t没有找到这名名学生 !\n");;
printf("\n\n\n请按enter键继续操作");
getchar();
}
else
printf("\n\n\n\n 敬告:输入错误,请按enter键返回菜单!!!\n");;
printf("\n\n\n请按enter键继续操作");
}
//更改学生记录
void Modify(Link l)
{
Node *p;
char findmess[20];
if(!l->next)
{
system("cls");
printf("\n\n\n\t\t\t 没有学生记录!\n");
printf("\n\n\n请按enter键继续操作");
getchar();
return;
}
system("cls");
printf("进入信息修改程序:\n\n");
display(l);
stringinput(findmess,10,"请输入要修改的学号:");
//输入学号并检验
p=Locate(l,findmess,"num");
//表示使用学号查找,并查找
if(p)//查找到
{
printf("学号:%s,\n ",p->date.num);
printf("姓名:%s, ",p->date.name);
stringinput(p->date.name,15,"请输入名字:");
printf("C语言成绩:%d, ",p->date.cgrade);
p->date.cgrade=numberinput("请输入C语言成绩[1-100]:");
printf("数学 成绩:%d, ",p->date.mgrade);
p->date.mgrade=numberinput("请输入数学 成绩[1-100]:");
printf("英语 成绩:%d, ",p->date.mgrade);
p->date.egrade=numberinput("请输入英语 成绩[1-100]:");
p->date.total=p->date.cgrade+p->date.mgrade+p->date.egrade;
p->date.ave=(float)(p->date.total/3);
p->date.mingci=0;
display(l);
saveflag=1;
}
else
printf("\n\n\t没有找到这名名学生 !\n");;
printf("\n\n\n请按enter键继续操作");
getchar();
}
/*插入学生纪录*/
void Insert(Link l)
{
Link p,v,newinfo;//P指向插入位置,newinfo指向新插入的记录
char ch,num[10],s[10];//s保存插入位置之前的学号num保存新学号
int flag;//表示学号是否存在
system("cls");
display(l);
if(l->next==NULL)
{
printf("\n\n\n请按enter键继续操作");
getchar();
return;
}
while(1)
{
stringinput(s,10,"请选择输入在哪个学号后 :");
flag=0;v=l->next;
while(v)//查询学号是否存在,float=1表示存在
{
if(strcmp(v->date.num,s)==0) {flag=1;break;}
v=v->next;
}
if(flag==1)
break;//若存在,退出目前循环
else
{
printf("\n\n\t\t这个学号不存在,是否再次输入 (y/n):");
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
{
continue;
}
else
{
return;
}
}
}
stringinput(num,10,"请输入新的学号:");
v=l->next;
while(v)
{
if(strcmp(v->date.num,num)==0)
{
printf(" 对不起,这个学号已存在 ! \n",num);
printheader();
printdate(v);
printf(" ---------------|--------------|---- |----|----|-------|-------|----|\n");
printf("\n\n\n");
printf("\n\n\n请按enter键继续操作");
getchar();
return;
}
v=v->next;
}
newinfo=(Node *)malloc(sizeof(Node));
if(!newinfo)
{
printf("\n allocate memory failure");
return;
}
strcpy(newinfo->date.num,num);
stringinput(newinfo->date.name,15,"姓名:");
newinfo->date.cgrade=numberinput("C语言成绩[1-100]:");
newinfo->date.mgrade=numberinput("数学 成绩[1-100]:");
newinfo->date.egrade=numberinput("英语 成绩[1-100]:");
newinfo->date.total=newinfo->date.cgrade+newinfo->date.mgrade+newinfo->date.egrade;
newinfo->date.ave=(float)(newinfo->date.total/3);
newinfo->date.mingci=0;
newinfo->next=NULL;
saveflag=1;
p=l->next;
while(1)
{
if(strcmp(p->date.num,s)==0)
{
newinfo->next=p->next;
p->next=newinfo;
break;
}
p=p->next;
}
display(l);
printf("\n\n");
printf("\n\n\n请按enter键继续操作");
getchar();
}
//统计学生信息
void Tongji(Link l)
{
Node *pm,*pe,*pc,*pt;//用来指向最高分的结构体
Node *r=l->next;
int countc=0,countm=0,counte=0;//保存3门成绩中不及格的人数
if(!r)
{
system("cls");
printf("\n 没有学生记录 !\n");
getchar();
return;
}
system("cls");
display(l);
pm=pe=pc=pt=r;
while(r)
{
if(r->date.cgrade<60) countc++;
if(r->date.mgrade<60) countm++;
if(r->date.egrade<60) counte++;
if(r->date.cgrade>=pc->date.cgrade) pc=r;
if(r->date.mgrade>=pm->date.mgrade) pm=r;
if(r->date.egrade>=pe->date.egrade) pe=r;
if(r->date.total>=pt->date.total) pt=r;
r=r->next;
}
printf("\n\t\t------------ 统计结果 -----------------\n");
printf("\t\t C 语言不及格人数: %d 人\n",countc);
printf("\t\t 数学 不及格人数: %d 人\n",countc);
printf("\t\t 英语 不及格人数: %d 人\n",countc);
printf("\t\t--------------------------------------------\n");
printf("\t\t 总分最高的学生 姓名:%s 总分:%d\n",pt->date.name,pt->date.total);
printf("\t\t英语成绩最高的学生 姓名:%s 分数:%d\n",pe->date.name,pe->date.egrade);
printf("\t\t数学成绩最高的学生 姓名:%s 分数:%d\n",pm->date.name,pm->date.mgrade);
printf("\t\tC语言成绩最高的学生姓名:%s 分数:%d\n\n",pc->date.name,pc->date.cgrade);
printf("\n\n\n请按enter键继续操作");
getchar();
}
//对运用插入法学生成绩进行排序
void Sort(Link l)
{
Link ll;//指向排序后的链表
Node *p,*rr,*s;
int i=0;
if(l->next==NULL)//没有学生信息,显出提示并返回菜单
{
system("cls");
printf("\n\t\t\t没有学生记录!\n\n\n");
getchar();
return;
}
ll=(Node*)malloc(sizeof(Node));
if(!ll)//申请内存失败
{
printf("\n allocate memory failure ");
return ;//返回菜单
}
ll->next=NULL;//使用前先赋值
system("cls");
display(l);//显示排序前
p=l->next;
while(p)//运用插入排序法
{
s=(Node*)malloc(sizeof(Node));
//新建结构体保存从原链表中取出的结构体
if(!s)
{
printf("\n allocate memory failure ");
return;
}
s->date=p->date;//取出原链表中的一节
s->next=NULL;
rr=ll;
while(rr->next!=NULL&&rr->next->date.total>=p->date.total)
{rr=rr->next;}
if(rr->next==NULL)
rr->next=s;
//若没有合适的位置,将P所指向的结构体添在链表尾部
else
{//将S结构体插入新结构体
s->next=rr->next;
rr->next=s;
}
p=p->next;//原链表的指针下移一个节点
}
l->next=ll->next;//ll存储的是已排序的链表的头指针
p=l->next;
while(p!=NULL)
{
i++;//节点序号等于名次
p->date.mingci=i;
p=p->next;
}
display(l);
saveflag=1;//全局变量标志信息未保存
printf("\n\t\t\t排序完成 !\n\n\n");
printf("\n\n\n请按enter键继续操作");
getchar();
}
/*保存*/
void Save(Link l)
{
FILE* fp;
Node *p;
int count=0;
fp=fopen("c:\\student.txt","wb");
if(fp==NULL)//打开文件失败
{
printf("\n open file error!\n");
printf("\n\n\n请按enter键继续操作");
getchar();
return;
}
p=l->next;
while(p)//将链表中的数据逐条写入文件
{
if(fwrite(p,sizeof(Node),1,fp)==1)
{
p=p->next;
count++;
}
else {
break;
}
}
if(count>0)
{
printf("\n\n\n\n\n\t\t\t保存完成,共有信息%d 条\n\n\n",count);
saveflag=0;//全局变量,标志数据以保存
}
else
{
system("cls");
printf("\t\t\t没有信息,无法保存!\n\n\n");
}
fclose(fp);
printf("\n\n\n请按enter键继续操作");
getchar();
}