学生学分管理系统.docx
《学生学分管理系统.docx》由会员分享,可在线阅读,更多相关《学生学分管理系统.docx(16页珍藏版)》请在冰豆网上搜索。
![学生学分管理系统.docx](https://file1.bdocx.com/fileroot1/2023-1/5/d93d2971-f935-4467-a354-5d924a537da7/d93d2971-f935-4467-a354-5d924a537da71.gif)
学生学分管理系统
#include
#include
#include
#include
#defineLENsizeof(Node)
#defineConsoleLength60
typedefstruct
{
charnum[11];/*学号*/
charname[10];/*姓名*/
intCredit;
}elemtype;
typedefstructnode
{
elemtypedata;
structnode*next;
}Node,*Nodeptr;
//赋值elem
voidCopyElem(elemtype*x,constchar*num,constchar*name,constintCredit);
voidCopyElem(Node*p,constelemtypex);
voidCopyElem(Node*p,constchar*num,constchar*name,constintCredit);
voidmenu();//菜单函数
voidto_menu();//返回菜单函数
voidPrintTheLink(NodeptrL);
//传入链表头指针,插入元素,排序方法(1降序,0升序,-1无序)
voidInsertElemToLink(NodeptrL,constelemtypex);
voidInsertElemToLink(NodeptrL,constchar*num,constchar*name,constintCredit);
intDelElem(NodeptrL,constintaID);
intDelElem(NodeptrL,constchar*num);
intSortTheLink(NodeptrL,intelemOrder=0);
intClearTheLink(NodeptrL);
intSortLink(NodeptrL);
intCreateLink(NodeptrL);
voidInsertElemToLink(NodeptrL);
intDeleteLink(NodeptrL);
voidsave(Node*L);
Node*load();
voidmain()
{
intfun;
NodeptrL;
L=newNode;
menu();//打印目录
L->next=NULL;
L->data.Credit=0;
while
(1)
{
printf("请输入功能号[0-7]:
",&fun);
scanf("%d",&fun);
switch(fun)
{
case0:
break;
case1:
CreateLink(L);//传进一个结构体指针的实参
break;
case2:
PrintTheLink(L);
break;
case3:
DeleteLink(L);
break;
case4:
InsertElemToLink(L);
break;
case5:
SortLink(L);
break;
case6:
save(L);break;
case7:
L=load();break;
default:
printf("输入错误!
");
break;
}
if(fun==0)break;
to_menu();
}
}
voidmenu()/*显示主菜单*/
{
system("cls");//清屏
printf("\n");
printf("\t\t★☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆★\n");
printf("\t\t☆☆\n");
printf("\t\t☆★☆学分管理系统☆★☆\n");
printf("\t\t☆☆\n");
printf("\t\t☆[0]退出[1]创建链表☆\n");
printf("\t\t☆☆\n");
printf("\t\t☆[2]输出学生记录[3]删除学生记录☆\n");
printf("\t\t☆☆\n");
printf("\t\t☆[4]插入学生记录[5]排序☆\n");
printf("\t\t☆☆\n");
printf("\t\t☆[6]保存到文件[7]从文件读取☆\n");
printf("\t\t☆☆\n");
printf("\t\t★☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆★\n\n");
}
voidto_menu()//等待用户按回车后回到主菜单
{
charc1,c2;
printf("\n\n\n按回车键返回主菜单...");
scanf("%c%c",&c1,&c2);//第一个字符吸收上次的确认回车键
menu();
}
//显示学生信息
voidPrintTheLink(NodeptrL)
{
//传入的L为储存学生信息的头结点
Nodeptrp;
inti=1;
intj,numlen,namelen;
p=L->next;//P指向下一个结点
for(j=0;j{
printf("*");
}
printf("\n");
printf("序号%*c学号%*c姓名%*c成绩\n",ConsoleLength/4-4,'',
ConsoleLength/4-4,'',ConsoleLength/4-4,'');//输出提示信息
//利用while循环打印出学生的信息
while(p)
{
numlen=(strlen(p->data.num)>11)?
11:
strlen(p->data.num);//判断输入的学号是否大于11个字符
namelen=(strlen(p->data.name)>10)?
10:
strlen(p->data.name);//判断输入的学号是否大于10个字符
printf("%d%*c%s%*c%s%*c%d\n",i++,ConsoleLength/4-i/10-1,'',
p->data.num,ConsoleLength/4-numlen,'',
p->data.name,ConsoleLength/4-namelen,'',p->data.Credit);//打印学生信息
p=p->next;//将指针移到下一个结点
}
//输出60个星号
for(j=0;j{
printf("*");
}
printf("\n");
}
voidCopyElem(Node*p,constelemtypex)
{
//将数组中的元素复制到结点中
inti;
for(i=0;i<11;i++)
{
p->data.num[i]=x.num[i];//复制学号到结点中
}
for(i=0;i<10;i++)
{
p->data.name[i]=x.name[i];//复制姓名到结点中
}
p->data.Credit=x.Credit;//复制成绩到结点中
}
voidCopyElem(Node*p,constchar*num,constchar*name,constintCredit)
{
elemtypex;
CopyElem(&x,num,name,Credit);
CopyElem(p,x);
}
voidCopyElem(elemtype*x,constchar*num,constchar*name,constintCredit)
{
strcpy((*x).name,name);//将姓名拷贝到结点中
strcpy((*x).num,num);//将学号拷贝到结点中
(*x).Credit=Credit;//将成绩拷贝到结点中
}
//voidInsertElemToLink(NodeptrL,constelemtypex,intelemOrder)
voidInsertElemToLink(NodeptrL,constelemtypex)
{
Node*p,*r;
p=newNode;
CopyElem(p,x);
r=L;
while((r->next)&&(r->next->data.Credit>p->data.Credit))
{
r=r->next;
}
p->next=r->next;
r->next=p;
L->data.Credit++;
}
voidInsertElemToLink(NodeptrL,constchar*num,constchar*name,constintCredit)
{
elemtypex;
CopyElem(&x,num,name,Credit);
InsertElemToLink(L,x);
}
voidInsertElemToLink(NodeptrL)
{
elemtypex;
intflag=1;
while(flag)
{
printf("请输入学生学号(不超过11位):
");
scanf("%s",&x.num);
printf("请输入该学生名字(不超过10位):
");
scanf("%s",&x.name);
printf("请输入该学生学分:
");
scanf("%d",&x.Credit);
InsertElemToLink(L,x);
printf("是否继续输入(1继续,0取消)?
\n");
scanf("%d",&flag);
}
PrintTheLink(L);
}
//创建链表
intCreateLink(NodeptrL)
{
//清除结点
ClearTheLink(L);
//将结点插入到链表中
InsertElemToLink(L);
return0;
}
//清除结点
intClearTheLink(NodeptrL)
{
Nodeptrp;
intnCount=0;
p=L->next;
while(p)
{
L->next=p->next;
delete(p);
p=L->next;
nCount++;
}
L->data.Credit=0;
returnnCount;
}
intSortTheLink(NodeptrL,intelemOrder)
{
intflag=1;
Node*p,*r,*q,*tmpRear;//p表示当前位置,r是下一位置,q是上一位置,tmp是冒泡排序的当前已排序结点
r=L->next;
if(!
r)//如果链表为空则返回
{
return0;
}
tmpRear=NULL;//定义一个结点指针用于在排序中控制每一趟冒泡的边界
while((L->next!
=tmpRear)&&(flag))
{
flag=0;
q=L;
p=L->next;
r=p->next;
//使用冒泡排序法将整个链表进行排序
while(r!
=tmpRear)//对tmpRear之前的结点进行冒泡
{
if(((1==elemOrder)&&(r->data.Credit>p->data.Credit))||
((0==elemOrder)&&(r->data.Creditdata.Credit)))
{//交换结点顺序
p->next=r->next;
r->next=p;
q->next=r;
flag=1;
}
q=q->next;
p=q->next;
r=p->next;
}
tmpRear=p;//修改冒泡的边界,以便进行下一趟冒泡
}
return1;
}
//排序函数
intSortLink(NodeptrL)
{
intc;
printf("请选择排序方法:
(1降序,0升序,-1取消排序)\n");
scanf("%d",&c);
SortTheLink(L,c);
PrintTheLink(L);
printf("排序结束!
\n");
return0;
}
//按照序号删除结点
intDelElem(NodeptrL,constintaID)
{
intidx=0;
Nodeptrp,r;
p=L->next;
r=L;
//查找序号
while((p)&&(++idx{
r=p;
p=p->next;
}
//此时p指向第aID个结点
//删除结点成功返回1
if(p)
{
r->next=p->next;//删除结点
deletep;//释放结点占用的内存空间
L->data.Credit--;
return1;
}
//序号不存在返回0
else
{
return0;
}
}
//按照学号删除结点
intDelElem(NodeptrL,constchar*num)
{
intflag=1;
Nodeptrp,r;
p=L->next;
r=L;
//查找学号
while((p)&&(flag))
{
if(strcmp(p->data.num,num)==0)//比较结点的学号与目标学号
{//如果相等则说明找到了要删除的结点
flag=0;//设置flag以便退出while循环
}
else
{//不相等则继续下一个结点
r=p;
p=p->next;
}
}
if(flag)//没找到结点
{
return0;
}
//删除找到的结点
else
{
r->next=p->next;//删除结点
deletep;//释放结点占用的内存空间
L->data.Credit--;
return1;
}
}
//删除记录
intDeleteLink(NodeptrL)
{
intflag=-1;
intsID=0;
intsDelAll=0;
charnum[11];
do
{
printf("选择欲删除记录(1指定序号删除,2指定学号删除,0全部删除,-1取消):
\n");
scanf("%d",&flag);
switch(flag)
{
case0:
printf("确定删除所有数据?
(1确定,0取消)\n");
scanf("%d",&sDelAll);
if(sDelAll)
{
printf("共删除%d条记录.\n",ClearTheLink(L));//调用ClearTheLink函数清除结点信息
}
break;
case1:
printf("请输入序号:
");
scanf("%d",&sID);
printf("共删除%d条记录.\n",DelElem(L,sID));//调用DelElem函数按序号删除
break;
case2:
printf("请输入欲删除的学生的学号:
");
scanf("%s",&num);
printf("共删除%d条记录.\n",DelElem(L,num));//调用DelElem函数按学号删除
break;
default:
break;
}
}while(-1return0;
}
/*保存数据到文件函数*/
voidsave(Node*L)
{
FILE*fp;/*定义指向文件的指针*/
Node*p;/*定义移动指针*/
fp=fopen("data","wb");/*为输出打开一个二进制文件,为只写方式*/
p=L;/*移动指针从头指针开始*/
while(p!
=NULL)/*如p不为空*/
{
fwrite(p,LEN,1,fp);/*写入一条记录*/
p=p->next;/*指针后移*/
}
fclose(fp);/*关闭文件*/
printf("保存成功!
\n");
}
/*从文件读数据函数*/
Node*load()
{
Node*p1,*p2,*L=NULL;/*定义记录指针变量*/
FILE*fp;/*定义指向文件的指针*/
if((fp=fopen("data","rb"))==NULL)/*打开一个二进制文件,为只读方式*/
{
printf("无法打开文件.\n");
return(L);
}
printf("\n正在读取!
\n");
p1=(Node*)malloc(LEN);/*开辟一个新单元*/
if(!
p1)
{
printf("读取失败!
\n");
return(L);
}
L=p1;/*申请到空间,将其作为头指针*/
while(!
feof(fp))/*循环读数据直到文件尾结束*/
{
if(fread(p1,LEN,1,fp)!
=1)break;/*如果没读到数据,跳出循环*/
p1->next=(Node*)malloc(LEN);/*为下一个结点开辟空间*/
if(!
p1->next)
{
printf("读取失败!
\n");
return(L);
}
p2=p1;/*使p2指向刚才p1指向的结点*/
p1=p1->next;/*指针后移,新读入数据链到当前表尾*/
}
p2->next=NULL;/*最后一个结点的后继指针为空*/
fclose(fp);
printf("读取数据成功!
\n");
return(L);
}