用c语言链表写的一个简单的学生管理系统

在大学由于在学完c语言之后老师布置了一个写学生管理系统的课设我写了一个简单的学生管理 系统,话不多说,直接上源代码。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char subject[6][20];  //用于储存学科的名字
int Nsubject;         //用于储存学科的数量
int Nstudent;         //用于储存学生的数量
char filename[50];    //用于储存文件的名字
FILE *FP;             //文件指针
typedef struct Student
{
    int studentid;     //储存学号
    char studentname[10];//储存学生姓名
    double studentscore[6];//储存学生成绩
    struct Student *next; //储存下一个节点的地址
} Student;
Student *head=NULL;  //定义头指针
void SaveData();     //此函数用于把链表中的数据保存到文件
void WriteData();    //此函数用于为新创建的文件写数据
void ReadData();     //此函数用于将文件中的数据读入链表中
void Openfile();     //此函数用于打开一个文件
void Append();       //此函数用于添加数据
void ModifyData(Student *p);//此函数用于修改学生的数据
Student* SearchByName();  /*此函数用于按学生姓名查找并返回地址*/
Student* SearchById();    /*此函数用于按学生学号查找并返回地址*/
void CreateFile();    /*此函数用于创建一个文件*/
void Remove();        //此函数用于删除文件
void List();           //此函数用列出学生信息
int Menu();          //菜单
void ModifyStudentData();  //此函数用于查找学生并修改此学生的信息
void DeletedData();       //此函数用于删除数据
int Quit();           //此函数用于退出系统
int main( )
{
  while(1)
  {

    switch(Menu())              //选择函数,实现某种功能
    {
      case 0:if(Quit())return 0;break;
      case 1:Openfile();break;
      case 2:SearchById();break;
      case 3:SearchByName();break;
      case 4:CreateFile();break;
      case 5:Remove();break;
      case 6:Append();break;
      case 7:SaveData();break;
      case 8:DeletedData();break;
      case 9:List();break;
      case 10:ModifyStudentData() ;break;
    }

  }
    return 0;
}
/*此函数用于把链表中的数据写入文件*/
void SaveData()
{
  fclose(FP);
  FP=fopen(filename,"w");     //改变文件的打开方式
  fprintf(FP, "%d %d ",Nstudent,Nsubject);  //向文件中写入学生人数和学科数目
  for(int i=0;i<Nsubject;i++)        //有几门学科执行几次循环
  {
    fprintf(FP,"%s ",subject[i]);   //将学科名写入文件
  }
  Student *p;
  while(head)
  {
    if(head->studentid==0)  //学号为0是删除标记
    {
      p=head->next;
      free(head);
      head=p;
    //  printf("__________________________\n");
      continue;
    }
    fprintf(FP,"%d %s ",head->studentid,head->studentname);//将学号和姓名写入文件
    for(int i=0;i<Nsubject;i++)
    {
      fprintf(FP,"%lf ",head->studentscore[i]);//按学科顺序依次将分数写入文件
    }
    p=head->next;
    free(head);
    head=p;
  }
  fclose(FP);     //关闭文件
  FP=NULL;
  head=NULL;
  printf("按任意键继续\n");
  getchar();
  getchar();
}
/*此函数用于为新创建的文件写数据*/
void WriteData()
{
    printf("请输入学生的人数:");
    scanf("%d",&Nstudent);
    printf("\n");
    printf("请输入考试科目的数量:");
    scanf("%d",&Nsubject);
    printf("\n");
    for(int i=0;i<Nsubject;i++)    //有几门学科循环几次
    {
        printf("请输入第%d门科目的名称:",i+1);
        scanf("%s",&subject[i]);
        printf("\n");
    }
    Student *p,*p1;
    for(int i=0;i<Nstudent;i++)    //有几名学生循环几次
    {
        p=(Student*)malloc(sizeof(Student));      //动态分配内存
        printf("请输入第%d名学生的学号:",i+1);
        scanf("%d",&p->studentid);
        printf("\n");
        printf("请输入第%d名学生的姓名:",i+1);
        scanf("%s",&p->studentname);
        printf("\n");
        for(int j=0;j<Nsubject;j++)
        {
            printf("请输入%s的成绩:",subject[j]);
            scanf("%lf",&p->studentscore[j]);
            printf("\n");
        }
        if(head==NULL)      //如果头指针为空指针将数据储存在头指针所指向的内存单元
        {
            head=p;
            p->next=NULL;
            //head->next=NULL;
            p1=head;
        }
        else
        {
           p1->next=p;
           p->next=NULL;
           p1=p1->next;
        }
    }
    printf("按任意键继续\n");
    getchar();
    getchar();
    return;
}
/*此函数用于将文件中的数据读入链表中*/
void ReadData()
{
        if(FP==NULL)
        {
          printf("请打开文件,按任意键继续");
          getchar();
          getchar();
          return;
        }
        fscanf(FP,"%d%d",&Nstudent,&Nsubject);  //从文件中读取学生的人数和学科的数量
        for(int i=0;i<Nsubject;i++)
        {
            fscanf(FP,"%s",&subject[i]);        //从文件中读取学科的名字
        }
        Student *p,*p1;
        for(int i=0;i<Nstudent;i++)
        {
            p=(Student*)malloc(sizeof(Student));      //动态分配内存
            fscanf(FP,"%d%s",&p->studentid,&p->studentname);
            for(int j=0;j<Nsubject;j++)
            {
                fscanf(FP,"%lf",&p->studentscore[j]);
            }
            if(head==NULL)      //如果头指针为空指针将数据储存在头指针所指向的内存单元
            {
                head=p;
                head->next=NULL;
                p1=head;
            }
            else
            {
               p1->next=p;
               p->next=NULL;
               p1=p1->next;
            }
        }
        printf("按任意键继续\n");
        getchar();
        getchar();
}
/*此函数用于打开一个文件*/
void Openfile()
{
    if(FP!=NULL)
    {
      printf("已有文件打开,请先保存已打开的文件\n");
      printf("按任意键继续\n");
      getchar();
      getchar();
    }
    printf("请输入你要打开的文件的名字:");
    scanf("%s",&filename);
    FP=fopen(filename,"r");
    if(FP==NULL)
    {
        printf("此文件不存在,按任意键继续\n");
        getchar();
        getchar();
        return;
    }
        ReadData();     //调用此函数
        printf("学生的人数为:%d\n",Nstudent);
        printf("按任意键继续\n");
        getchar();
}
/*此函数用于在链表后面添加数据*/
void Append( )
{
    if(FP==NULL)
    {
      printf("请打开一个文件,按任意键继续\n");
      getchar();
      getchar();
      return ;
    }
        Student *p;
        Student *p1;
        p1=head;
       while(p1->next)
       {
           p1=p1->next;
       }
       printf("输入要添加学生的人数:\n");
       int n;
       scanf("%d",&n);
       for(int i=0;i<n;i++)
       {    p=(Student*)malloc(sizeof(Student));
            printf("请输入第%d名学生的学号:",++Nstudent);
            scanf("%d",&p->studentid);
            printf("\n");
            printf("请输入第%d名学生的姓名:",Nstudent);
            scanf("%s",&p->studentname);
            printf("\n");
            for(int i=0;i<Nsubject;i++)
            {
              printf("请输入%s的成绩:",subject[i]);
              scanf("%lf",&p->studentscore[i]);
              printf("\n");
            }
            p1->next=p;
            p->next=NULL;
            p1=p1->next;
      }
      printf("按任意键继续\n");
      getchar();
      getchar();
}
/*此函数用于修改学生的数据*/
void ModifyData(Student *p)
{
  printf("请输入学生的新名字\n");
  scanf("%s",&p->studentname);
  printf("请输入学生的新学号:\n");
  scanf("%d",&p->studentid);
  for(int i=0;i<Nsubject;i++)
  {
    printf("请输入%s的新成绩:\n",subject[i]);
    scanf("%lf",&p->studentscore[i]);
  }
}
/*此函数用于按学生姓名查找*/
Student* SearchByName()
{
  if(FP==NULL)
  {
    printf("请打开一个文件,按任意键继续\n");
    getchar();
    return NULL;
  }
    char name[10];
    printf("请输入你要查找学生的名字\n" );
    scanf("%s",&name );
    Student *p;
    p=head;
    while(p)   //当链表为空是结束循环
    {
      if(p->studentid==0)
      {
        p=p->next;
        continue;
      }
      if(!strcmp(p->studentname,name))   //比较两个字符数组,如果形同进入循环
      {
        printf("姓名:%s\n",p->studentname);
        printf("学号:%d\n",p->studentid);
        for(int i=0;i<Nsubject;i++)
        {
          printf("%s:%.2lf\n",subject[i],p->studentscore[i]);
        }
        printf("按任意键继续\n");
        getchar();
        getchar();
        return p;
      }
      p=p->next;    //指向链表的下一个节点
    }
      printf("没有查到这名学生\n");
      //printf("按任意键继续\n");
      return p;
}
/*此函数用于按学生学号查找*/
Student* SearchById()
{
  if(FP==NULL)
  {
    printf("请打开一个文件,按任意键继续\n");
    getchar();
    return NULL;
  }
    int id;
    printf("请输入你要查找学生的学号\n" );
    scanf("%d",&id );
    Student *p;
    p=head;
    while(p)
    {
      if(p->studentid==0)  //学号为零是删除标记
      {
        p=p->next;
        continue;
      }
      if(p->studentid==id)  //如果学号相同进入循环
      {
        printf("姓名:%s\n",p->studentname);
        printf("学号:%d\n",p->studentid);
        for(int i=0;i<Nsubject;i++)
        {
          printf("%s:%.2lf\n",subject[i],p->studentscore[i]);
        }
       printf("按任意键继续\n");
        getchar();
        getchar();
        return p;
      }
      p=p->next;
    }
    printf("没有查到这名学生\n");
    //printf("按任意键继续\n");
    return p;
}
/*此函数用于创建一个文件*/
void CreateFile()
{
  if(head!=NULL)
  {
    printf("还有数据未保存,请保存,按任意键继续");
    getchar();
    return;
  }
  printf("请输入要创建的文件的名字:");
  scanf("%s",&filename);
  FP=fopen(filename,"w");
  WriteData();   //调用此函数

}
void Remove()//此函数用于删除文件
{
  printf("输入要删除的文件名\n");
  scanf("%s",&filename);
  remove(filename);        //删除文件
  printf("按任意键继续\n");
  getchar();
  getchar();
}
void List()//此函数用列出学生信息
{
  if(FP==NULL)
  {
    printf("请打开文件,按任意键继续\n");
    getchar();
    getchar();
    return ;
  }
    Student *p;
    p=head;
    while(p)       //当链表为空是结束循环
    {
      if(p->studentid==0)
      {
        p=p->next;
        continue;
      }
      printf("学生姓名:%s\n",p->studentname);
      printf("学号:%d\n",p->studentid);
      for(int i=0;i<Nsubject;i++)
      {
        printf("%s:%.2lf\n",subject[i],p->studentscore[i]);
      }
      printf("+++++++++++++++++++++++++++++++++++++++++\n");
      p=p->next;
    }
    printf("按任意键继续\n");
    getchar();
    getchar();
 }
 void ModifyStudentData()  //此函数用于查找学生并修改此学生的信息
 {
   int a;
   Student *p;
   printf("\t1按学号查找\n");
   printf("\t2按姓名查找\n");
   scanf("%d",&a);
   if(a==1)
   {
     p=SearchById();  //调用此函数并返回查找到数据的链表节点地址
     ModifyData(p);   //执行此函数,修改此节点上的数据
   }
   else
   {
     p=SearchByName(); //调用此函数并返回查找到数据的链表节点地址
     ModifyData(p);     //执行此函数,修改此节点上的数据
   }
   printf("按任意键继续\n");
   getchar();
   getchar();
 }
 int Menu()//菜单
 {
     system("cls");
     printf("\n\n\n\n\n");//输入回车,形成格式;
     printf("\t\t\t|...........学生管理系统..............|\n");
     printf("\t\t\t|1.打开文件\n");
     printf("\t\t\t|2.按学号查找学生\n");
     printf("\t\t\t|3.按姓名查找学生\n");
     printf("\t\t\t|4.创建文件\n");
     printf("\t\t\t|5.删除文件\n");
     printf("\t\t\t|6.添加数据\n");
     printf("\t\t\t|7.保存\n");
     printf("\t\t\t|8.删除学生信息\n");
     printf("\t\t\t|9.列出学生信息\n");
     printf("\t\t\t|10.修改学生信息\n");
     printf("\t\t\t|0.退出\n");
     printf("\t\t\t|.....................................|\n");
     int choice;
     if(scanf("%d",&choice)!=1||choice<0||choice>10)
     {
         printf("请输入0~10任意一个数字\n");
    }
     else
    {
     return choice;
   }
 }
 void DeletedData()       //此函数用于删除数据
 {
   Student *p;
   ///p1=(Student*)malloc(sizeof(Student));
   printf("\t1按学号查找\n");
   printf("\t2按姓名查找\n");
   int a;
   scanf("%d",&a);
   if(a==1)
     p=SearchById();
   else
     p=SearchByName();
     if(p==NULL)
     {
       printf("按任意键继续\n");
       getchar();
       getchar();
       return;
     }
     printf("是否确认删除?y/n\n");
     char b[1];
     scanf("%s",&b);
     if(b[0]=='y'||b[0]=='Y')
     {
       p->studentid=0;
       Nstudent--;
     }

 printf("按任意键继续\n");
 getchar();
 getchar();
 }
 int Quit()    //此函数用于退出操作;
{
  if(FP!=NULL)
  {
    printf("还有文件未保存请先保存文件\n");
    printf("按任意键继续\n");
    getchar();
    getchar();
    return 0;
  }
  else
  return 1;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值