⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 学生成绩管理系统.c

📁 //不知道为什么在插入和删除操作的时候会出现错误
💻 C
字号:
//学生成绩管理系统(C)
//作者:鱼儿妙 提交时间:2006-6-29 10:34:07 [推荐给好友] 

//不知道为什么在插入和删除操作的时候会出现错误,其他还好,大家帮忙看看

//******xuesheng********
//*******头文件(.h)*****
#include <stdio.h>//标准输入输出
#include <string.h>//字符串函数
#include <ctype.h>//字符函数
#include <stdlib.h>//其它说明
#include <malloc.h>
#include <math.h>
#define N 3//定义常数
#define NULL 0
typedef struct z1//定义数据结构
{
 char no[11];
 char name[15];
 int score[N];
 float sum;
 float average;
 int order;
 struct z1 *next;
}STUDENT;
//*******以下是函数原形**********
STUDENT *init();//初始化函数
STUDENT *create();//创建链表
STUDENT *del(STUDENT *h);//删除记录
STUDENT *insert(STUDENT *h);//插入记录
void print(STUDENT *h);//显示所有记录
void search(STUDENT *h);//查找
int menu_select();//菜单函数
//----------------------------------------------------------------------------
//*********主函数开始*************
void main()
{
 STUDENT *head;//链表定义头指针
 head=init();//初始化链表
 for(;;)//无限循环
 {
  switch(menu_select())//调用主菜单函数.返回值为整数,作开关语句的条件
  {//值不同,执行的函数不同,break不能省略
  case 0:head=init();break;
  case 1:head=create();break;
  case 2:head=del(head);break;
  case 3:print(head);break;
  case 4:search(head);break;
  case 5:head=insert(head);break;
  case 6:exit(0);
  }
 }
}
//******菜单函数******
menu_select()
{
 int i;
 char *menu[]={"**********菜单**********",
  "0.初始化",
  "1.输入记录",
  "2.从表中删除记录",
  "3.显示单链表中所有记录",
  "4.按照姓名查找记录",
  "5.插入记录到表中",
  "6.退出"};
 for(i=0;i<8;i++)
  printf("%s\n",menu[i]);
 int c;
 char s[3];
 do{
  printf("\n请输入你需要操作选项的编号:");
  scanf("%s",s);
  c=atoi(s);//将字符串转化为整数型
 }while(c<0||c>14);//选项保证在0到14之间
 return(c);
}
//-----------------------------------------------------------------------------
//输入字符串并验证长度

inputs(char *prompt,char *s,int count)
{
 char p[255];
 do{
  printf(prompt);//显示提示
  scanf("%s",p);
  if(strlen(p)>count)printf("\n字符过长\n");//字符长度验证,超过则重新输入
 }while(strlen(p)>count);
 strcpy(s,p);//将输入繁荣字符串复制到字符串 S中
}

//**********初始化链表**********
STUDENT *init()
{
 return NULL;
}
//**********创建链表**********
STUDENT *create()
{
 int i,s;
 STUDENT *h=NULL,*info;//STUDENT指向结构体的指针
 for(;;)//无限循环
 {
  info=(STUDENT *)malloc(sizeof(STUDENT));//申请空间
  if(!info)//如果info指针为空
  {
   printf("输出内存溢出");
   return NULL;
  }
  inputs("输入学号:",info->no,11);//输入学号并验证
  if(info->no[0]=='@')break;//若学号首字符为@则结束输入
  inputs("输入姓名:",info->name,15);//输入姓名并验证
  printf("请输入成绩:\n",N);
  s=0;//学生总成绩初值为0
  for(i=0;i<N;i++)//N门课循环N次
  {
   do{
    printf("第%d门课",i+1);
    scanf("%d",&info->score[i]);//输入成绩
    if(info->score[i]>100||info->score[i]<0)//成绩大于0小于100
    printf("输入错误,请重新输入");//错误提示信息
   }while(info->score[i]>100||info->score[i]<0);
   s=s+info->score[i];//累加成绩计算总分
  }
  info->sum=s;//保存总分
  info->average=(float)s/N;//求出平均值
  info->order=0;//未排序前此值为0
  info->next=h;//将头结点作为新输入结点的后继结点
  h=info;//新输入结点为新的头结点
 }
 return(h);//返回头指针
}
//**********输入链表中结点的信息**********
void print(STUDENT *h)
{
 int i=0;//统计记录条数
 STUDENT *p;
 p=h;//处值为头指针
 printf("\n\n***************************学生信息**************************\n");
 printf("| rec | no | name | scl | sc2 | sc3 |  sum  | average | order |\n");
 printf("|-----|----|------|-----|-----|-----|-------|---------|-------|\n");
 while(p!=NULL)
 {
  i++;
  printf("|%5d|%-5s|%-6s|%5d|%5d|%5d| %4.2f | %4.2f | %3d |\n",i,p->no,p->name,p->score[0],p->score[1],p->score[2],p->sum,p->average,p->order);
  p=p->next;
 }
 printf("**************************结束**************************\n");
}
//**********删除记录**********
STUDENT *del(STUDENT *h)
{
 STUDENT *p,*q;//p为要删除结点的指针,q为其前趋指针
 char s[11];//存放学号
 printf("请输入要删除的学号:\n");
 scanf("%s",s);
 q=p=h;//给P和q赋初值头指针
 while(strcmp(p->no,s)&&p!=NULL)//当要找的指针不正确时
 {
  p=q;
  p=p->next;
 }
 if(p==NULL)//若p为空则链表中无此结点
  printf("\n无%s号学生\n",s);
 else//当p不为空时显示查找的记录
 {
  char a;
  printf("***************查找结果****************\n");
  printf("| no | name | scl | sc2 | sc3 | sum | average | order |\n");
  printf("|----|------|-----|-----|-----|-----|---------|-------|\n");
  printf("|%-10s|%-15s|%4d|%4d|%4d| %4.2f | %4.2f | %3d |\n",p->no,p->name,p->score[0],p->score[1],p->score[2],p->sum,p->average,p->order);
  printf("**************************结束**************************\n");
  printf("输入d进行删除操作");
  scanf("%s",a);
   if(p==h)//若p=h则删除结点是头结点
    h=p->next;//修改头指针指向下条记录
   else
    q->next=p->next;//不是头指针时将p的后继结点作为q的后继结点
   printf("\n%d号学生已被删除",s);
 }
 return(h);//返回头指针
}
//**********查找记录**********
void search(STUDENT *h)
{
 STUDENT *p;//移动指针
 char s[15];//存放姓名的字符数组
 printf("请输入要查找的名字\n");
 scanf("%s",s);//输入姓名
 p=h;//将头指针赋给P
 while(strcmp(p->name,s)&&p!=NULL)//当记录的姓名不是要查找的姓名或指针不为空时
  p=p->next;//移动指针,指向下一结点
 if(p==NULL)//若指针为空
  printf("\n无%d号学生\n",s);//显示无该学生
 else//显示查找结果
 {
  printf("\n\n***************************查找结果**************************\n");
  printf("| no | name | scl | sc2 | sc3 | sum | average | order |\n");
     printf("|----|------|-----|-----|-----|-----|---------|-------|\n");
     printf("|%-10s|%-15s|%4d|%4d|%4d| %4.2f | %4.2f | %3d |\n",p->no,p->name,p->score[0],p->score[1],p->score[2],p->sum,p->average,p->order);
     printf("**************************结束**************************\n");
 }
}
//**********插入记录*********
STUDENT *insert(STUDENT *h)
{
   STUDENT *p,*q,*info; //p指向要插入的结点,q指向第一个结点,info指新插入记录
   char s[11];  //保存插入结点位置的学号
   int s1,i;
   printf("请输入插入点的学号\n");
   scanf("%s",s);   //输入插入点学号
   printf("\n请输入新的记录信息\n"); //提示输入记录信息
   info=(STUDENT *)malloc(sizeof(STUDENT));   //申请空间
   if(!info)
   {
      printf("\nout of memory");   //如没有申请到,内存溢出
      return NULL;             //返回空指针
   }
   inputs("请输入学号:",info->no,11); //输入学号
   inputs("请输入姓名:",info->name,15); //输入姓名
   printf("请输入第%d门课的分数\n",N);  //提示输入分数
   s1=0;    //保存新记录的总分,初值为0
   for(i=0;i<N;i++)    //N门课程循环N次输入成绩
   {
      do{        //对数据进行验证,保证在0~100之间
  printf("分数为%d:",i+1);
  scanf("%d",&info->score[i]);
  if(info->score[i]>100||info->score[i]<0)
     printf("输入错误,重新输入\n");
      }while(info->score[i]>100||info->score[i]<0);
      s1=s1+info->score[i];    //计算总分
   }
   info->sum=s1;    //将总分存入新记录中
   info->average=(float)s1/N;  //计算均分
   info->next=NULL;     //设后继指针为空
   p=h;               //将指针赋值给p
   q=h;             //将指针赋值给q
   while(strcmp(p->no,s)&&p!=NULL)    //查找插入位置
   {
      q=p;                 //保存指针p,作为下一个p的前驱
      p=p->next;          //将指针p后移
   }
   if(p==NULL)      //如果p指针为空,说明没有指定结点
    if(p==h)      //同时p等于h,说明链表为空
     h=info;   //新记录则为头结点
    else
     q->next=info;  //p为空,但p不等于h,将新结点插在表尾
    else
     if(p==h)     //p不为空,则找到了指定结点
     {
      info->next=p; //如果p等于h,则新结点插入在第一个结点之前
      h=info;    //新结点为新的头结点
     }
     else
     {
      info->next=p;   //不是头结点,则是中间某个位置,新结点的后继为p
      q->next=info;  //新结点作为q的后继结点
     }
     printf("\n ----学号为%s的学生信息已经被建立----\n",info->name);
     return(h);         //返回头指针
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -