单链表实现学生成绩管理系统的增删改查

写在前面:这个代码除了实现基本的数据增删改查外,还对数据进行了按学号排序输入,输出到文档中!同时对界面实现了优化!对数据插入方法使用插入排序!以及人数的统计,多种查询方式等!代码是很久之前写的,当时刚好学了单链表这一块,最近碰巧在磁盘里看到了就把它发了出来,顺便把文件操作内容补充了!

//全局定义两个指针变量(头指针和尾指针);头指针用来遍历,尾指针用来添加Student成员;实现结果就不附图了,谢谢阅览!!!
//腾出一点时间顺便把文件处理内容也补充了,读者自行测试!!!!

#pragma warning(disable:4996)            //屏蔽某些非标准C库的警告!
//#define _CRT_SECURE_NO_WARNINGS            //防止scanf警告,也可直接用scanf_s;
#include 
#include 
#include 
#include 
#include 

//成绩表结构体
typedef struct stu
{
    long num;
    char name[10];
    char sex[4];
    float Math;
    float Chinese;
    float English;
    struct stu* next;
}STU;

FILE *fp;
char filename[20];
STU* Head = NULL;  //定义一个指针
STU* End = NULL;   //尾结点

//创建头结点和尾结点
void CreatList()
{
    Head = (struct stu*)malloc(sizeof(struct stu));
    Head->next = NULL;  
    STU* End = Head;    
}

//文件加载
void LoadData()
{
    CreatList();
    STU* ptr;
    printf("\n\n\n\n        请输入文件名:");
    scanf("%s", filename);
    if ((fp = fopen(filename, "a+")) == NULL)
    {
        printf("\n                Error!!!");
        printf("\n                Error!!!");
        printf("\n                Error!!!");
        printf("\n              文件打开失败!!!");
        exit(0);
    }
    ptr = (struct stu*)malloc(sizeof(struct stu));
    ptr->next = NULL;
    while (fscanf(fp, "%ld  %s  %s  %f  %f  %f\n", &ptr->num, ptr->name, ptr->sex, &ptr->Math, &ptr->Chinese, &ptr->English) != EOF)
    {
        if (Head->next == NULL)
        {
            Head->next = ptr;
            End = ptr;
        }
        else
        {
            End->next = ptr;
            End = End->next;
        }
        ptr = (struct stu*)malloc(sizeof(struct stu));
        ptr->next = NULL;
    }
    free(ptr);       
    fclose(fp);
}


//写入数据到文件中,并保存文件
void SaveData()
{
    STU* ptr = Head->next;
    if ((fp = fopen(filename, "w")) == NULL)
    {
        printf("\n                Error!!!");
        printf("\n                Error!!!");
        printf("\n                Error!!!");
        printf("\n              文件打开失败!!!");
        exit(0);
    }
    while (ptr != NULL)
    {
        fprintf(fp, "%ld  %s  %s  %6.2f  %6.2f  %6.2f\n", ptr->num, ptr->name, ptr->sex, ptr->Math, ptr->Chinese, ptr->English);
        ptr = ptr->next;
    }
    fclose(fp);
}

//添加学生成绩信息
void AddStudent()
{
    int n, i;
    printf("\n请输入您要添加的学生人数:");
    scanf("%d", &n);
    for (i = 0; inext = NULL;
        printf("\n            要添加的第%d个学生的信息如下:\n", i + 1);
        printf("\n请输入第%d个学生学号: ", i + 1);
        scanf("%ld", &pNew->num);

        //检查学号是否重复
        STU* temp = Head->next;
        while (temp != NULL)
        {
            if (temp->num == pNew->num)
            {
                printf("\n              学号重复,请重新输入!!!\n");
                printf("\n请重新输入第%d个学生学号: ", i + 1);
                scanf("%ld", &pNew->num);
                temp = Head->next;        //重新遍历比较
                continue;
            }
            else
                temp = temp->next;
        }
        printf("请输入第%d个学生姓名: ", i + 1);
        scanf("%s", pNew->name);
        printf("请输入第%d个学生性别: ", i + 1);
        scanf("%s", pNew->sex);
        printf("请输入第%d个学生数学成绩: ", i + 1);
        scanf("%f", &pNew->Math);
        while (1)
        {
            if ((pNew->Math)< 0 || (pNew->Math > 100))
            {
                printf("\n            输入成绩有误,请检查!!!\n");
                printf("\n请重新输入第%d个学生数学成绩: ", i + 1);
                scanf("%f", &pNew->Math);
            }
            else break;
        }
        printf("请输入第%d个学生语文成绩: ", i + 1);
        scanf("%f", &pNew->Chinese);
        while (1)
        {
            if ((pNew->Chinese)< 0 || (pNew->Chinese > 100))
            {
                printf("\n            输入成绩有误,请检查!!!\n");
                printf("\n请重新输入第%d个学生语文成绩: ", i + 1);
                scanf("%f", &pNew->Chinese);
            }
            else break;
        }
        printf("请输入第%d个学生英语成绩: ", i + 1);
        scanf("%f", &pNew->English);
        while (1)
        {
            if ((pNew->English)< 0 || (pNew->English) > 100)
            {
                printf("\n            输入成绩有误,请检查!!!\n");
                printf("\n请重新输入第%d个学生英语成绩: ", i + 1);
                scanf("%f", &pNew->English);
            }
            else break;
        }

        //按学号排序,边添加边排序;
        if (Head->next == NULL)
        {
            Head->next = pNew;        //作为首元素
            End = Head->next;
            //End->next = NULL;
        }
        else
        {
            if (pNew->num > End->num)
            {
                End->next = pNew;
                End = End->next;
                //End->next = NULL;
            }
            else
            {
                STU* p1 = Head->next;
                if (pNew->num > p1->num)        //表明链表中已经至少存在2个成员(至少存在首和尾);
                {
                    STU* p2 = p1->next;
                    while (1)
                    {
                        if ((pNew->num > p1->num) && (pNew->num < p2->num))
                        {
                            pNew->next = p2;
                            p1->next = pNew;
                            break;
                        }
                        else
                        {
                            p1 = p1->next;
                            p2 = p2->next;
                        }
                    }

                }
                else
                {
                    pNew->next = p1;
                    Head->next = pNew;
                }

            }
        }
    }
    printf("\n\n             学生信息全部添加完成!!!\n");
}

//通过前驱结点删除学生成绩信息
void DeleteStudent()
{
    int num;
    printf("\n请输入您要删除的学生的学号:");
    scanf("%ld", &num);
    STU* pre = Head;        //表中没有数据时,pre为空;

    while (1)
    {
        if (pre->next && (pre->next->num == num))
        {
            STU* q = pre->next;
            pre->next = pre->next->next;
            //pre->next = NULL;
            printf("\n\n                删除操作成功!!!\n");
            printf("\n             已删除的学生成绩信息如下!!!\n\n");
            printf("学号\t\t姓名\t性别\t数学\t语文\t英语\t\n\n");
            printf("%ld\t%s\t%s\t%.2f\t%.2f\t%.2f\n", q->num, q->name, q->sex, q->Math, q->Chinese, q->English);
            free(q);
            return;
        }
        else
        {
            if (pre->next != NULL)
                pre = pre->next;
            else
            {
                printf("\n\n                信息删除失败!!!\n");
                return;
            }
        }
    }

    //寻找前驱结点的第二种方法
    /*
    while (pre->next && (pre->next->num != num))
    pre = pre->next;
    if (pre->next)            //pre为前驱
    {
    STU* q = pre->next;
    pre->next = pre->next->next;
    //pre->next = NULL;
    printf("\n\n                删除操作成功!!!\n");
    printf("\n             已删除的学生成绩信息如下!!!\n\n");
    printf("学号\t\t姓名\t性别\t数学\t语文\t英语\t\n\n");
    printf("%ld\t%s\t%s\t%.2f\t%.2f\t%.2f\n", q->num, q->name, q->sex, q->Math, q->Chinese, q->English);
    free(q);
    }
    else
    printf("\n\n                信息删除失败!!!\n");
    */

}


//更改学生成绩信息
void AlterStudent()
{
    int num;
    printf("\n请输入您要更改学生的学号:");
    scanf("%ld", &num);
    STU* change = Head->next;
    while (change && (change->num != num))
        change = change->next;
    if (change)
    {
        printf("\n更改后的学号:");
        scanf("%ld", &change->num);
        printf("\n更改后的姓名: ");
        scanf("%s", change->name);
        printf("\n更改后的性别: ");
        scanf("%s", change->sex);
        printf("\n更改后的数学成绩: ");
        scanf("%f", &change->Math);
        printf("\n更改后的语文成绩: ");
        scanf("%f", &change->Chinese);
        printf("\n更改后的英语成绩: ");
        scanf("%f", &change->English);
        printf("\n\n            学生信息已经更改完毕!!!\n");
    }
    else
        printf("\n\n            学生信息不存在,无法更改!!!\n");
}

//查询学生成绩信息
void SeekStudent()
{
    while (1)
    {
        printf("\n\n请选择查询方式??? 按学号:1 / 按姓名:2:  ");
        int k;
        scanf("%d", &k);
        switch (k)
        {
        case 1:
        {
                  int num;
                  printf("\n请输入您要查找学生的学号:");
                  scanf("%ld", &num);
                  STU* find = Head->next;
                  while (find && (find->num != num))
                      find = find->next;
                  if (find)
                  {
                      printf("\n查询学生信息如下:\n\n");
                      printf("学号\t\t姓名\t性别\t数学\t语文\t英语\n\n");
                      printf("%ld\t%s\t%s\t%.2f\t%.2f\t%.2f\n", find->num, find->name, find->sex, find->Math, find->Chinese, find->English);
                  }
                  else
                      printf("\n\n            没有查询到该学生信息!!!\n");
                  return;

        }
        case 2:
        {
                  printf("\n请输入您要查找学生的姓名:");
                  char name1[20];
                  scanf("%s", name1);
                  STU* find = Head->next;
                  while (find && (strcmp(find->name, name1) != 0))
                      find = find->next;
                  if (find)
                  {
                      printf("\n查询学生信息如下:\n\n");
                      printf("学号\t\t姓名\t性别\t数学\t语文\t英语\n\n");
                      printf("%ld\t%s\t%s\t%.2f\t%.2f\t%.2f\n", find->num, find->name, find->sex, find->Math, find->Chinese, find->English);
                  }
                  else
                      printf("\n\n            没有查询到该学生信息!!!\n");
                  return;
        }
        default:
        {
                   printf("\n\n查询方式错误!!! 请重新选择查询方式\n");
                   break;
        }
        }
    }
}

//输出全部学生信息
void DisplayAll()
{
	STU* p = Head->next;
	int len = 0;
	float SX = 0;
	float YW = 0;
	float YY = 0;
	printf("\n			    全部学生成绩信息如下!!!\n\n");
	while (p != NULL)
	{
		float sum = p->Math + p->Chinese + p->English;
		printf("学号:%ld  姓名:%s  性别:%s  数学:%.2f  语文:%.2f  英语:%.2f  总分:%.2f\n\n", p->num, p->name, p->sex, p->Math, p->Chinese, p->English, sum);
		SX = SX + p->Math;
		YW = YW + p->Chinese;
		YY = YY + p->English;
		p = p->next;
		len++;
		while (p == NULL)
		{
			printf("\n\n			   成绩系统含学生总人数为:%d 人\n", len);
			printf("\n			   学生数学平均成绩:%.2f 分\n", SX/len);
			printf("\n			   学生语文平均成绩:%.2f 分\n", YW/len);
			printf("\n			   学生英语平均成绩:%.2f 分\n", YY/len);
			return;
		}
	}
	printf("\n				Error!!!");
	printf("\n				Error!!!");
	printf("\n				Error!!!");
	printf("\n			  成绩表中数据为空!!!\n");
	return;
}

//视图界面
void VeiwInterface()
{
    system("cls");
    printf("   \t***********************************************************\n");
    printf("   \t*        欢迎使用学生成绩管理系统            *\n");
    printf("   \t***********************************************************\n\n");
    printf("   \t*|*\t\t   1.添加学生成绩信息   \t\t*|*\n\n");
    printf("   \t*|*\t\t   2.删除学生成绩信息   \t\t*|*\n\n");
    printf("   \t*|*\t\t   3.更改学生成绩信息   \t\t*|*\n\n");
    printf("   \t*|*\t\t   4.查询学生成绩信息   \t\t*|*\n\n");
    printf("   \t*|*\t\t   5.输出全部学生信息   \t\t*|*\n\n");
    printf("   \t*|*\t\t   6.--- 退出系统 ---   \t\t*|*\n\n");
    printf("   \t*-*-----------------------------------------------------*-*\n");
    printf("\n请选择功能??? 输入序号:<1--6>:");
}

//需要执行的功能选择
void ChoiceFunction(int k)
{
    while (1)
    {
        switch (k)
        {
        case 1:
        {
                  while (1)
                  {
                      system("cls");
                      AddStudent();
                      printf("\n\n是/否继续添加学生成绩信息??? 继续:1 / 退出:0:  ");
                      int select1 = getch() - 48;
                      switch (select1)
                      {
                      case 1: break;
                      case 0: return;
                      default:
                      {
                                 printf("\n\n            输入错误!!! 按任意键回到主界面\n\n");
                                 system("pause");
                                 return;
                      }
                      }
                  }
        }

        case 2:
        {
                  while (1)
                  {
                      system("cls");
                      DeleteStudent();
                      printf("\n\n是/否继续删除学生成绩信息??? 继续:1 / 退出:0:  ");
                      int select2 = getch() - 48;
                      switch (select2)
                      {
                      case 1: break;
                      case 0: return;
                      default:
                      {
                                 printf("\n\n            输入错误!!! 按任意键回到主界面\n\n");
                                 system("pause");
                                 return;
                      }
                      }
                  }
        }

        case 3:
        {
                  while (1)
                  {
                      system("cls");
                      AlterStudent();
                      printf("\n\n是/否继续更改学生成绩信息??? 继续:1 / 退出:0:  ");
                      int select3 = getch() - 48;
                      switch (select3)
                      {
                      case 1: break;
                      case 0: return;
                      default:
                      {
                                 printf("\n\n            输入错误!!! 按任意键回到主界面\n\n");
                                 system("pause");
                                 return;
                      }
                      }
                  }
        }

        case 4:
        {
                  while (1)
                  {
                      system("cls");
                      SeekStudent();
                      printf("\n\n是/否继续查询学生成绩信息??? 继续:1 / 退出:0:  ");
                      int select4 = getch() - 48;
                      switch (select4)
                      {
                      case 1: break;
                      case 0: return;
                      default:
                      {
                                 printf("\n\n            输入错误!!! 按任意键回到主界面\n\n");
                                 system("pause");
                                 return;
                      }
                      }
                  }
        }

        case 5:
        {
                  while (1)
                  {
                      system("cls");
                      //system("color 17");
                      DisplayAll();
                      printf("\n\n是/否退出显示??? 退出:1 / 刷新:0:  ");
                      int select5 = getch() - 48;
                      switch (select5)
                      {
                      case 1: return;
                      case 0: break;
                      default:
                      {
                                 printf("\n\n            输入错误!!! 按任意键回到主界面\n\n");
                                 system("pause");
                                 return;
                      }
                      }
                  }
        }

        case 6:
        {
                  SaveData();
                  printf("\n\n再次确认是/否退出系统??? 退出:1 / 取消:0:  ");
                  int select6 = getch() - 48;
                  switch (select6)
                  {
                  case 1: exit(0);
                  case 0: return;
                  default: return;
                  }
        }

        default:
        {
                   printf("\n\n            输入错误!!! 按任意键回到主界面重新选择\n\n");
                   system("pause");
                   return;
        }
        }
    }
}

//主函数
void main()
{
    LoadData();
    int key;
    while (1)
    {
        VeiwInterface();
        key = getch() - 48;        //返回的是字符的ASCLL值,‘1’= 49.....;
        ChoiceFunction(key);
    }
}

添加成员

单链表实现学生成绩管理系统的增删改查_第1张图片

 

显示输出:

 

单链表实现学生成绩管理系统的增删改查_第2张图片

查找学员:

单链表实现学生成绩管理系统的增删改查_第3张图片

更改学员:

单链表实现学生成绩管理系统的增删改查_第4张图片

删除学员:

单链表实现学生成绩管理系统的增删改查_第5张图片

显示输出

 单链表实现学生成绩管理系统的增删改查_第6张图片

此外对于存入文件中,博主在这里没有直接给出代码,读者可以自行设计(用文件指针实现),不理解的地方可以留言一起讨论,谢谢指教!

补充:前几天把文件处理内容补充了,今天把代码发了上来,可以试着用“feof”去代替我的“EOF”,看看结果怎样!!!!

 

 

 

你可能感兴趣的:(单链表实现学生成绩管理系统的增删改查)