学生管理系统(C语言版+数据结构之链表)

数据结构中最简单的也就是顺序表以及链表,在链表中可以完成管理系统之类的,只要掌握这个学生管理系统,其他的管理系统都可以做,只要稍加改动,就可以改编成其它系统的,这里我先写出一个学生管理系统,后面,我会写一个疫苗管理系统,大家可以对比着看。

这里采用多文件编码方式进行编写且具有文件操作

这部分是StudentSystem.c文件中的

#include "singleList.h"
struct Node* list = NULL;
void systemMenu()
{
  //这里是菜单栏
  printf("-------【学生管理系统】-------\n");
  printf("\t\t0.退出系统\n");
  printf("\t\t1.插入信息\n");
  printf("\t\t2.浏览信息\n");
  printf("\t\t3.删除信息\n");
  printf("\t\t4.修改信息\n");
  printf("\t\t5.查找信息\n");
  //printf("\t\t6.保存信息\n");//这里不用专门做,因为系统会自动保存到文件之中
  printf("-----------------------------\n");
  printf("请输入0--5:");
  //每次交互,若没告诉别人这个地方需要交互,则会有瑕疵
}
void keyDown()//按键交互
{
  int userkey;
  struct student tempData;//存储临时的data
  scanf("%d",&userkey);
  switch(userkey)
  {
  case 0:
      printf("\t\t【退出系统】\n");
      system("pause");//使屏幕悬停
      exit(0);
      break;
  case 1:
      printf("\t\t【插入信息】\n");
      printf("请输入姓名,学号,年龄,电话,住址:");
      scanf("%s%s%d%s%s",tempData.name,tempData.num,&tempData.age,tempData.tel,tempData.addr);
      //整型要进行取地址
      insertNodeByHead(list,tempData);
      break;
  case 2:
      printf("\t\t【浏览信息】\n");
      printList(list);
      break;
  case 3:
      printf("\t\t【删除信息】\n");
      printf("请输入要删除学生的姓名:");
      scanf("%s",tempData.name);
      deleteNodeByAppoinName(list,tempData.name);
      saveInfoToFile("student.txt",list);
      break;
  case 4:
      printf("\t\t【修改信息】\n");
      printf("请输入要修改学生的学号:");
      scnaf("%s",tempData.num);
      if(searchNodeByAppoinNum(list,tempData.num) == NULL)
      {
        printf("未找到相关信息,修改失败!!\n");
      }
      else
      {
        struct Node* curNode = searchNodeByAppoinNum(list,tempData.num);
        printf("请输入该生新名字,学号,年龄,电话,住址:");
        scanf("%s%s%d%s%s",curNode->data.name,curNode->data.num,curNode->data.age,curNode->data.tel,curNode->data.addr);//为什么能这样改,因为这里返回的是一个指针,可以直接作用到它的数据域
        saveInfoToFile("student.txt",list);//保存到哪里,是哪个链表
      }
      break;
      
  case 5:
      printf("\t\t【查找信息】\n");
      printf("请输入要查找的学生的学号:");
      scanf("%s",tempData.num);
      if(searchNodeByAppoinNum(list,tempData.num) == NULL)//进行判断,看是否查找到了信息
      {
        printf("未找到相关信息,查找失败!!\n");
      }
      else
      {
        printNode(searchNodeByAppoinNum(list,tempData.num));
      }
      break;
  default:
      printf("输入错误!请重新输入:\n");
      break;
  }
}
int main()
{
  list = createList();
  while(1)
  {
    systemMenu();
    keyDown();
    system("pause");
    system("cls");
  }
  system("pause");
  return 0;
}

这里是singleList.h文件中的
//也就是单链表

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student
{
  char name[20];//名字
  char num[10];//学号
  int age;//年龄
  char tel[20];//电话号码
  char addr[20];//家庭地址
};
//写数据结构,死方法:
//1、抽象单一个体
//2、描述最初状态:初始化-->初始化变量
//3、插入、删除
//4、打印遍历
struct Node
{
  struct student data;
  struct Node* next;
};
//1、链表使什么东西:就是结构体变量和结构体变量连接在一起
//2、指针第二种变为变量的方式:动态内存分配
//3、用第一个结点表示整个链表
struct Node* createList()
{
  //链表中的两种类型:
  //有表头链表:第一个结点不存储数据
  //无表头链表:第一个结点存储数据
  //1、产生一个结构体变量
  struct Node* listHeadNode = (struct Node*)malloc(sizeof(struct Node));
  //2、初始化链表
  listHeadNode->next = NULL;
  return listHeadNode;
}
struct Node* createNode(struct student data)//链表的表头和结点是一样的,没有什么区别
{
  struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
  newNode->data = data;
  newNode->next = NULL;
  return newNode;
}
//插入哪个链表,插入的数据是多少:功能就是录入信息
void insertNodeByHead(struct Node* listHeadNode,struct student data)
{
  //创建插入的结点:
  struct Node* newNode = createNode(data);
  //要是想不清楚就画图
  newNode->next = listHeadNode->next;//连的是newNode跟listHeadNode之间的线
  listHeadNode->next = newNode;//连的是listheadNode跟newNode之间的线,而newNode是新插入的结点
}
//删除 根据姓名 进行删除
void deleteNodeByAppoinName(struct Node* listHeadNode,char* name)
{
  struct Node* posFrontNode = listHeadNode;
  struct Node* posNode = listHeadNode->next;
  //在删除之前,首先要判断链表是否为空
  if(posNode == NULL)
  {
    printf("无相关内容,无法删除!!");
    return ;
  }
  else
  {
    while(strcmp(posNode->data.name,name))
    {
      posFrontNode = posNode;
      posNode = posFrontNode->next;
      //不可能一直找下去,要有个停的地方
      if(posNode == NULL)
      {
        printf("无相关内容,无法删除!!");
        return ;
      }
    }
    //找到了
    posFrontNode->next = posNode->next;
    free(posNode);
  }
}
//查找   根据学号  进行查找
struct Node* searchNodeByAppoinNum(struct Node* listHeadNode,char* num)
{
  struct Node* pMove = listHeadNode->next;//这里是移动的指针
  if(pMove == NULL)
  {
    return pMove;
  }
  else
  {
    while(strcmp(pMove->data.num,num))
    {
      pMove = pMove->next;//这里学号如果不同,就得一直往下走
      if(pMove == NULL)//防止其发生中断错误,所以要进行防御性编程
      {
        break;
      }
    }
    return pMove;//返回所找到的结点
  }
}
//打印:插入时的当前结点
void printNode(struct Node* curNode)
{
  printf("姓名\t学号\t年龄\t电话\t\t住址\n");
  printf("%s\t%s\t%d\t%s\t%s\n",curNode->data.name,curNode->data.num,curNode->data.age,curNode->data.tel,curNode->data.addr);
}
//打印:就是系统的浏览信息
void printList(struct Node* listHeadNode)//表头打印
{
  struct Node* pMove = listHeadNode->next;
  printf("姓名\t学号\t年龄\t电话\t\t住址\n");
  while(pMove)
  {
    printf("%s\t%s\t%d\t%s\t%s\n",pMove->data.name,pMove->data.num,pMove->data.age,pMove->data.tel,pMove->data.addr);
    pMove->next;
  }
  printf("\n");
}
//文件操作
//读的是哪个文件,保存到哪个信息中去
void readInfoFromFile(char* fileName,struct Node* listHeadNode)
{
  //定义文件指针
  //打开文件
  FILE* fp = fopen(fileName,"r");//文件以读的形式进行打开
  //如果文件不存在
  if(fp == NULL)
  {
    fp = fopen(fileName,"w");//这里文件就以写的形式进行打开,
                             //如果文件不存在,这里系统就会自动生成一个文件
  }
  //用格式化读取
  struct student tempData;
  while(fscanf(fp,"%s\t%s\t%d\t%s\t%s\n",tempData.name,tempData.num,&tempData.age,tempData.tel,tempData.addr)!=EOF)//按照这个格式进行读取文件,从哪里读,从文件指针哪里读,所以最前面是fp
  //加\t是以表格的形式进行写,以表格的形式进行读
  {
    insertNodeByHead(listHeadNode,tempData);
    memset(&tempData,0,sizeof(tempData));//开始进行初始化一下
  }
  fclose(fp);
}

//存储文件信息
//存储到哪个文件去,把哪一个链表中的信息存储到这里来
void saveInfoToFile(char* fileName,struct Node* listHeadNode)
{
  FILE* fp = fopen(fileName,"w");
  //用格式化打印到文件中去
  struct Node* pMove = listHeadNode->next;
  while(pMove)
  {
    fprintf(fp,"%s\t%s\t%d\t%s\t%s\n",pMove->data.name,pMove->data.num,pMove->data.age,pMove->data.tel,pMove->data.addr);
    pMove = pMove->next;
  }
  fclose(fp);
  //修改需要保存文件
  //查找不需要保存文件
}

这就是完整的链表学生管理系统,希望对大家有用。好好看,好好研究这个链表的格式,对以后写个啥是非常有帮助的!!!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值