/*使用本学期所学习的结构化程序设计思想,设计并实现一个“学生信息管理系统”,系统功能与技术要求如下:
(1)系统基本功能:增加、修改、删除、浏览、查找、排序、统计等。
(2)系统必须使用链表等数据结构表示系统中管理的数据对象。
(3)数据约束功能:对输入数据要有一定的有效性检测,不合法的输入数据应有出错提示且要求重新输入。
(4)界面要求:至少分两层菜单。提供良好的人机界面,方便用户进行相关操作。
(5)如有余力,请把数据的操作的结果以文件形式保存起来,
(此处分功能逐一贴出每一个功能函数的代码)*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>//清屏的头文件
int n;//定义全局变量
typedef struct Student
{
long id;
char name[20];
int age;
float score;
struct Student *next;
}Student;
//动态申请内存结点
Student *getNode()
{
Student *p1;
p1=(Student *)malloc(sizeof(Student));
return (p1);
}
//主函数
int main()
{
Student *creat(void);
void Add(Student *head);
void *Find(Student *head);
void Change(Student *head);
void Look(Student *head);
void Sort(Student *head);
void Statisstics(Student *head);
int judge(Student *head,long id1);
Student *pt;
Student *p1,*p2;
long a;//暂时存放学号
int k,m;
pt=creat();//返回链表的第一个节点的地址
for(;;){
printf("------------------------欢迎使用简易版学生信息管理系统------------------------\n"
"一、功能菜单如下:\n"
"------增加学生信息请按1\n"
"------删除学生信息请按2\n"
"------查找学生信息请按3\n"
"------修改学生信息请按4\n"
"------浏览学生信息请按5\n"
"------排序学生信息请按6\n"
"------统计学生信息请按7\n"
"------清屏模式请按8\n");
printf("请输入你要选择的功能:(输入大于7的数结束访问)\n");
scanf("%d",&k);
if(k>=1&&k<=7)
{
if(k==2)//删除学生信息的函数
{
printf("请输入你要删除学生信息的学号:\n");
scanf("%ld",&a);
for(;;)//判断学号是否存在
{
m=judge(pt,a);
if(m==1)break;
else
{printf("你输入的学号不存在!请重新输入:\n");
scanf("%ld",&a);}
}
for(p1=pt;p1&&p1->id!=a;p2=p1,p1=p1->next);//遍历一边数据
if(!p1){printf("不存在该学号!");}//跑完没有找到存在的值
else
{
if(p1==pt)//删除头节点
{
pt=pt->next;//跳过第一个 节点,直接指向下一个
free(p1);
p1=NULL;
}
else//删除中间尾节点
{
p2->next=p1->next;//p1指向的data被删除了
free(p1);
p1=NULL;
}
printf("删除成功!\n");
printf("\n");
}
}
else{
switch(k)
{
case 1:Add(pt);break;
case 3:Find(pt);break;
case 4:Change(pt);break;
case 5:Look(pt);break;
case 6:Sort(pt);break;
case 7:Statisstics(pt);break;
}
}
}
else if(k==8)//清屏模式开关
{
system("cls");
}
else if(k>=9)
{printf("-----------------------欢迎再次使用!-------------------------");break;}
}
return 0;
}
//创建链表
Student *creat(void)//定义函数,此函数返回一个指向链表头的指针
{
Student *p1,*p2,*head;//p2为每一次指向下一个申请单元的指针,head为头指针
p1=p2=getNode();//开辟一个新单元
printf("请输入学生的学号、名字、年龄和c语言成绩:(格式:575657(学号为0读取结束) jik 23 89.8)\n");
scanf("%ld %s %d %f",&p1->id,p1->name,&p1->age,&p1->score);//输入第一个学生的学号和名字,年龄及成绩
head=NULL;//头指针悬空
while(p1->id!=0)
{
n=n+1;
if(n==1)head=p1;//头文件指向p1
else p2->next=p1;//p2指向p1
p2=p1;
p1=getNode();//开辟动态储存区,把起始地址赋给p1
scanf("%ld %s %d %f",&p1->id,p1->name,&p1->age,&p1->score);//输入第二位同学的信息
}
p2->next=NULL;//尾指针悬空
return (head);//返回头文件的地址
}
//1增加信息的函数
void Add(Student *head)
{
int i,j;
Student *p1,*p2;
p1=head;
if(head!=NULL)
{
for(;p1!=NULL;)
{p2=p1;
p1=p1->next;}
}
printf("请输入要增加的学生信息人数:\n");
scanf("%d",&j);
printf("请输入学生信息:\n");
for(i=0;i<j;i++)
{
p1=getNode();//开辟新单元
p2->next=p1;
p2=p1;
scanf("%ld %s %d %f",&p1->id,p1->name,&p1->age,&p1->score);
}
p2->next=NULL;//尾指针悬空
printf("增加成功!\n");
printf("\n");
}
//3查找信息的函数
void *Find(Student *head)
{
int judge(Student *head,long id1);//调用判断学号是否存在的函数的声明
Student *p1,*p2;
long a;
int m;
p1=head;
printf("请输入你要查找的学生信息的学号:\n");
for(;;)//不断输入学号,直到输入正确的学号
{
scanf("%ld",&a);
for(;;)//判断学号是否存在
{
m=judge(p1,a);
if(m==1)break;
else
{printf("你输入的学号不存在!请重新输入:\n");
scanf("%ld",&a);}
}
do
{//找到与用户输入的信息相同的结点
if(p1->id!=a)
{
p2=p1;
p1=p1->next;
}//找到了
else break;
}while(p1!=head);//遍历查找
if(p1!=NULL)
{ printf("你要查找的信息如下:\n");
printf("学号:%ld 名字:%s 年龄:%d c语言成绩:%.2f\n",p1->id,p1->name,p1->age,p1->score);break;}//输出要找的学生信息
}
printf("\n");
}
//4修改信息的函数
void Change(Student *head)
{
Student *p1,*p2;
long a;
int i,m;
char name1[20];
int age1;
float score1;
p1=head;
printf("请输入你要修改的学生信息的学号:\n");
scanf("%ld",&a);
for(;;)//判断学号是否存在
{
m=judge(p1,a);
if(m==1)break;
else
{printf("你输入的学号不存在!请重新输入:\n");
scanf("%ld",&a);}
}
do
{//找到与用户输入的信息相同的结点
if(p1->id!=a)
{
p2=p1;
p1=p1->next;
}//找到了
else break;
}while(p1!=head);//遍历查找
if(p1!=NULL)
{
printf("--------------------修改名字请按1-----------------\n"
"----------------------修改年龄请按2------------------\n"
"--------------------修改c语言成绩请按3-------------\n");
scanf("%d",&i);
if(i==1)
{printf("修改为:\n");
scanf("%s",&name1);
strcpy(p1->name,name1);}
else if(i==2)
{
printf("修改为:\n");
scanf("%d",&age1);
p1->age=age1;
}
else if(i==3)
{
printf("修改为:\n");
scanf("%f",&score1);
p1->score=score1;
}
}
printf("\n");
}
//5浏览学生信息的函数
void Look(Student *head)
{
Student *p1;
p1=head;
printf("学生的全部信息如下:\n");
for(;p1!=NULL;p1=p1->next)
{printf("学号:%ld 名字:%s 年龄:%d c语言成绩:%.2f\n",p1->id,p1->name,p1->age,p1->score);\
if(p1->next==NULL)break;}
printf("\n");
}
//6排序学生信息的函数
void Sort(Student *head)
{
Student *p1,*p2;
int k;
float t;
p1=p2=getNode();
p1=head;
printf("-------------请输入你要选择的功能---------------\n"
"1、年龄排序从小到大请按1\n"
"2、成绩从大到小排序请按2\n");
scanf("%d",&k);
if(k==1)
{
for(;p1!=NULL;p1=p1->next)//选定的位置,从第一个位置开始
{
for(p2=p1->next;p2!=NULL;p2=p2->next)
{
if(p2->age<p1->age)
{
t=p2->age;
p2->age=p1->age;
p1->age=t;
}
}
}
printf("学生年龄从小到大排序信息如下:\n");
p1=head;
for(;p1!=NULL;p1=p1->next)
{printf("学号:%ld 名字:%s 年龄:%d c语言成绩:%.2f\n",p1->id,p1->name,p1->age,p1->score);\
if(p1->next==NULL)break;}
}
else if(k==2)//成绩冒泡法排序
{
for(;p1!=NULL;p1=p1->next)
{
for(p2=p1->next;p2!=NULL;p2=p2->next)
{
if(p2->score>p1->score)
{
t=p2->score;
p2->score=p1->score;
p1->score=t;
}
}
}
printf("学生c语言成绩从大到小排序信息如下:\n");
p1=head;
for(;p1!=NULL;p1=p1->next)
{printf("学号:%ld 名字:%s 年龄:%d c语言成绩:%.2f\n",p1->id,p1->name,p1->age,p1->score);\
if(p1->next==NULL)break;}
}
printf("\n");
}
//7统计学生信息的函数
void Statisstics(Student *head)
{
Student *p1,*p2;
int k,count=0;
printf(" ----------1、统计c语言成绩不及格的人数请按1!\n"
"-----------2、统计已成年的学生人数请按2!\n");
scanf("%d",&k);
if(k==1)
{
for(p1=head;p1!=NULL;p1=p1->next)
{
if(p1->score<60)count++;
}
printf("c语言成绩不及格的人数为:%d\n",count);
}
else if(k==2)
{
for(p1=head;p1!=NULL;p1=p1->next)
{
if(p1->age>=18)count++;
}
printf("已成年的学生人数为:%d\n",count);
}
printf("\n");
}
//判断学号是否存在的函数
int judge(