c语言文件读写_学生信息管理系统(C语言\单向链表\文件读写)

bab4a416312915f5a4b34ff6a8503dd1.png

最近在复习数据结构,早上刚复习完链表,就想到了学生信息管理系统这个经典的大作业,然后呢,花了一早上加一中午的功夫给重新实现了一遍,里面可能会有写的不好的地方,但也代表了我实现的一些想法,在这里我将分享出来。

我是在Ubuntu上用vim写的,当然了这些代码window下也可以运行。文章最后有完整代码。

一 实现功能

1、查看学生信息

2、添加学生信息。

3、删除学生信息

4、修改学生信息

5、保存学生信息到文件

6、刷新学生信息(从文件中恢复学生信息)

0、退出系统

二 表示学生的数据结构

struct 

三 实现菜单

void meum()
{
  printf("n   *****************************   n");
  printf("         学生信息管理系统          n");
  printf("   *****************************   n");
  printf("           系统菜单功能            n");
  printf("   *****************************   n");
  printf("          1.查看学生信息           n");
  printf("          2.添加学生信息           n");
  printf("          3.删除学生信息           n");
  printf("          4.修改学生信息           n");
  printf("          5.保存学生信息           n");
  printf("          6.刷新学生信息           n");
  printf("          0.退出系统               n");
}

四 实现增加学生的功能

void creat_node(LinkList *L)
{
  char name;
  LinkList *node=NULL;
  LinkList *temp=L->next;  //作为链表连接的中间点
  node=(LinkList *)malloc(sizeof(LinkList));  //分配内存
  if(node==NULL)
  {
    printf("分配普通节点内存出错!");
    exit(1);
  }
  memset(node,0,sizeof(LinkList));
  printf("n请输入学生序号:");
  scanf("%d",&node->data.number);
  printf("n请输入学生名:");
  scanf("%s",node->data.name);
  printf("n请输入学生成绩:");
  scanf("%d",&node->data.score);
  printf("n请输入学生年龄:");
  scanf("%d",&node->data.age);

  L->next=node;                                                                                                                                          
  node->next=temp;
}

五 显示学生信息

void show_student(LinkList *L)
{
  LinkList *p=L->next;
  int i=0;
  printf("n    **************************      n");
  printf("            学生信息                n");
  printf("    **************************      n");
  printf("   序号    姓名    成绩    年龄 n");
  while(p)
  {
    printf("      %d      %s      %d      %d     n",p->data.number,p->data.name,p->data.score,p->data.age);
    i++;                                                                                                                                                 
    p=p->next;
  }
}

六 删除学生

可以选择

1、按序号删除。

2、按姓名删除。

void delete_student(LinkList *L)
{
  int x=0;
  int number;
  char name[10];
  LinkList *temp,*pre;
  temp=L->next;
  while(1)
  {
    printf("n    请选择:");
    printf("n    1.按序号删除!");
    printf("n    2.按姓名删除!");
    printf("n    请输入选择:");
    scanf("%d",&x);
    if(x==1 || x==2)
      break;
    else 
      printf("n   输入错误,请重新输入!");
  }
  if(x==1)            //根据输入的序号找到学生并删除
  {
    printf("n    请输入要删除的学生序号:");
    scanf("%d",&number);
    while(temp->data.number!=number && temp->next!=NULL)
    {
      pre=temp;
      temp=temp->next;
    }
    if(temp->data.number==number)
    {
      pre->next=temp->next;
      free(temp);
    }
    else
    {
      printf("n    没有所要删除的学生序号!");
    }
  }
  else if(x==2)      //根据输入的姓名找到学生并删除
  {
    printf("n     请输入要删除的学生名字:");
    scanf("%s",name);
    while(strcmp(temp->data.name,name)!=0 && temp->next!=NULL)
    {
      pre=temp;
      temp=temp->next;
    }
    if(strcmp(temp->data.name,name)==0)
    {
      pre->next=temp->next;
      free(temp);
    }
    else
    {
      printf("n     没有要删除的学生姓名!");
    }
  }
}

七 修改学生信息

首先找到学生,然后对找到的学生信息进行修改。

可以选择按序号和按姓名来找学生。

找到学生后,可以选择修改学生的任意一项信息。

void modify_student(LinkList *L)
{
  int x=0;
  int number;
  char name[10];
  LinkList *temp;
  temp=L->next;
  while(1)
  {
    printf("n    请选择:");
    printf("n    1.知道要修改学生的序号!");
    printf("n    2.知道要修改学生的名字!");                                                                                                             
    printf("n    请输入选择:");
    scanf("%d",&x);
    if(x==1 || x==2)
      break;
    else
      printf("n   输入错误,请重新输入!");
  }
  if(x==1)
  {
    printf("n    请输入要修改学生的序号:");
    scanf("%d",&number);
    while(temp->data.number!=number && temp->next!=NULL)
    {
      temp=temp->next;
    }
    if(temp->data.number==number)
    {
      printf("n     已经找到要修改学生的信息!");
    }
    else
    {
      printf("n    没有要修改学生的序号!");
    }
  }
  else if(x==2)
  {
    printf("n     请输入要修改学生的名字:");
    scanf("%s",name);
    while(strcmp(temp->data.name,name)!=0 && temp->next!=NULL)
    {
      temp=temp->next;
    }
    if(strcmp(temp->data.name,name)==0)
    {
      printf("n     已经找到要修改学生的信息!");
    }
    else
    {
      printf("n     没有要修改学生的姓名!");
    }
  }
  printf("n     ************************");
  printf("n   姓名:%s  序号:%d  成绩:%d  年龄:%d",temp->data.name,temp->data.number,temp->data.score,temp->data.age);
  do{
    printf("n     请选择:");
    printf("n     1.修改序号!");
    printf("n     2.修改名字!");
    printf("n     3.修改成绩!");
    printf("n     4.修改年龄!");
    printf("n     请输入选择:");
    scanf("%d",&x);
  }while(x<1 || x>4);
  if(x==1)
  {
    printf("n     请输入修改后的序号:");
    scanf("%d",&temp->data.number);
  }
  if(x==2)
  {
    printf("n     请输入修改后的名字:");
    scanf("%s",temp->data.name);
  }
  if(x==3)
  {
    printf("n     请输入修改后的成绩:");
    scanf("%d",&temp->data.score);
  }
  if(x==4)
  {
    printf("n     请输入修改后的年龄:");
    scanf("%d",&temp->data.age);
  }

}

八 保存到文件

void save(LinkList *L)
{
  FILE *fp;
  int i=0;
  LinkList *temp;                                                                                                                                        
  temp=L->next;
  if((fp=fopen("student.txt","a"))==NULL)
  {
    printf("n     无法打开文件!");
    exit(1);
  } 
  while(temp!=NULL)
  {
    i++;
    fprintf(fp,"%d %s %d %d n",temp->data.number,temp->data.name,temp->data.score,temp->data.age);
    printf("n     第%d个已经保存!",i);
    temp=temp->next;
  }
  fclose(fp);
}

九 从文件中恢复

void refresh(LinkList *L)
{
  FILE *fp;
  LinkList *node=NULL;                                                          
  LinkList *temp=L->next;
  node=(LinkList *)malloc(sizeof(LinkList));
  if(node==NULL)
  {
    printf("分配普通节点内存出错!");
    exit(1);
  }
  memset(node,0,sizeof(LinkList));  
  fp=fopen("student.txt","r");
  if(fp==NULL)
  {
    printf("n     无法打开文件!");
    exit(1);
  }
  while(!feof(fp))
  {
    fscanf(fp,"%d %s %d %d",&node->data.number,node->data.name,&node->data.score,&node->data.age);
    L->next=node;
    node->next=temp;
    temp=node;
    node=(LinkList *)malloc(sizeof(LinkList));
    if(node==NULL)
    {
      printf("分配普通节点内存出错!");
      exit(1);
    }
    memset(node,0,sizeof(LinkList));
  }                                                                                                                                                      
  printf("n     已经成功刷新学生信息!");
}

十 主函数

主函数中先创建一个头节点(不保存学生信息,便于操作空链表),然后进入主菜单,功能选择模块被我独立成一个函数,代码在主函数后面。

void main()
{ 
  int i;
  LinkList *L=NULL;
  L=(LinkList *)malloc(sizeof(LinkList));
  if(L==NULL)
  { 
    printf("分配头节点内存出错!");
    exit(1);
  }
  memset(L,0,sizeof(LinkList));
  L->next=NULL;
  
  int stop=1;
  while(1)
  { 
    meum();
    choice(&stop,L);
    if(stop==0)
      break;
    printf("n     下一步操作:");
    printf("n     1.返回主界面");
    printf("n     2.退出系统");
    printf("n     请输入操作:");
    scanf("%d",&i);
    if(i==2)
      break;
  }
}
void choice(int *stop,LinkList *L)
{
  int num;
  printf("nn          请输入菜单选项:");
  scanf("%d",&num);
  switch (num)
  {
    case 0: *stop=0; break;
    case 1: show_student(L); break;
    case 2: creat_node(L); break;
    case 3: delete_student(L); break;
    case 4: modify_student(L); break;
    case 5: save(L); break;
    case 6: refresh(L); break;
    default: printf("      请在0-6中间选择n");
  }
}

十一 优化建议

上面有一些写法可以进行优化的,但是因为这只是一个小项目没必要分那么多函数(分了引用次数也十分有限),并且这样更符合我的思路(一功能一模块),就没有进行优化。可以优化的如下:

1、将有复用的代码段独立写成函数,减少代码函数,例如选择和分配节点空间那里独立成函数。

2、将部分较长的函数进行功能分割,便于阅读。

十二 扩展建议

一、增加排序功能。

二、增加代码修改后写回文件时的检验是否修改的功能。

三、扩展界面。

十四 全部代码

#include<stdio.h>                                                                                                                                        
#include<stdlib.h>
#include<string.h>

struct student
{ 
  char name[10];
  int score;
  int number;
  int age;
};
struct LNode
{ 
  struct student data;
  struct LNode *next;
};
typedef struct LNode LinkList;


void meum();
void choice(int *stop,LinkList *L);
void creat_node(LinkList *L);
void show_student(LinkList *L);
void delete_student(LinkList *L);
void modify_student(LinkList *L);
void save(LinkList *L);
void refresh(LinkList *L);

void main()
{ 
  int i;
  LinkList *L=NULL;
  L=(LinkList *)malloc(sizeof(LinkList));
  if(L==NULL)
  { 
    printf("分配头节点内存出错!");
    exit(1);
  }
  memset(L,0,sizeof(LinkList));
  L->next=NULL;
  
  int stop=1;
  while(1)
  { 
    meum();
    choice(&stop,L);
    if(stop==0)
      break;
    printf("n     下一步操作:");
    printf("n     1.返回主界面");
    printf("n     2.退出系统");
    printf("n     请输入操作:");
    scanf("%d",&i);
    if(i==2)
      break;
  }
}

void choice(int *stop,LinkList *L)
{
  int num;
  printf("nn          请输入菜单选项:");
  scanf("%d",&num);
  switch (num)
  {
    case 0: *stop=0; break;
    case 1: show_student(L); break;
    case 2: creat_node(L); break;
    case 3: delete_student(L); break;
    case 4: modify_student(L); break;
    case 5: save(L); break;
    case 6: refresh(L); break;
    default: printf("      请在0-6中间选择n");
  }
}

void meum()
{
  printf("n   *****************************   n");
  printf("         学生信息管理系统          n");
  printf("   *****************************   n");
  printf("           系统菜单功能            n");
  printf("   *****************************   n");
  printf("          1.查看学生信息           n");
  printf("          2.添加学生信息           n");
  printf("          3.删除学生信息           n");
  printf("          4.修改学生信息           n");
  printf("          5.保存学生信息           n");
  printf("          6.刷新学生信息           n");
  printf("          0.退出系统               n");
}

void creat_node(LinkList *L)
{
  char name;
  LinkList *node=NULL;
  LinkList *temp=L->next;  //作为链表连接的中间点
  node=(LinkList *)malloc(sizeof(LinkList));  //分配内存
  if(node==NULL)
  {
    printf("分配普通节点内存出错!");
    exit(1);
  }
  memset(node,0,sizeof(LinkList));
  printf("n请输入学生序号:");
  scanf("%d",&node->data.number);
  printf("n请输入学生名:");
  scanf("%s",node->data.name);
  printf("n请输入学生成绩:");
  scanf("%d",&node->data.score);
  printf("n请输入学生年龄:");
  scanf("%d",&node->data.age);

  L->next=node;                                                                                                                                          
  node->next=temp;
}

void show_student(LinkList *L)
{
  LinkList *p=L->next;
  int i=0;
  printf("n    **************************      n");
  printf("            学生信息                n");
  printf("    **************************      n");
  printf("   序号    姓名    成绩    年龄 n");
  while(p)
  {
    printf("      %d      %s      %d      %d     n",p->data.number,p->data.name,p->data.score,p->data.age);
    i++;                                                                                                                                                 
    p=p->next;
  }
}

void delete_student(LinkList *L)
{
  int x=0;
  int number;
  char name[10];
  LinkList *temp,*pre;
  temp=L->next;
  while(1)
  {
    printf("n    请选择:");
    printf("n    1.按序号删除!");
    printf("n    2.按姓名删除!");
    printf("n    请输入选择:");
    scanf("%d",&x);
    if(x==1 || x==2)
      break;
    else 
      printf("n   输入错误,请重新输入!");
  }
  if(x==1)            //根据输入的序号找到学生并删除
  {
    printf("n    请输入要删除的学生序号:");
    scanf("%d",&number);
    while(temp->data.number!=number && temp->next!=NULL)
    {
      pre=temp;
      temp=temp->next;
    }
    if(temp->data.number==number)
    {
      pre->next=temp->next;
      free(temp);
    }
    else
    {
      printf("n    没有所要删除的学生序号!");
    }
  }
  else if(x==2)      //根据输入的姓名找到学生并删除
  {
    printf("n     请输入要删除的学生名字:");
    scanf("%s",name);
    while(strcmp(temp->data.name,name)!=0 && temp->next!=NULL)
    {
      pre=temp;
      temp=temp->next;
    }
    if(strcmp(temp->data.name,name)==0)
    {
      pre->next=temp->next;
      free(temp);
    }
    else
    {
      printf("n     没有要删除的学生姓名!");
    }
  }
}

void modify_student(LinkList *L)
{
  int x=0;
  int number;
  char name[10];
  LinkList *temp;
  temp=L->next;
  while(1)
  {
    printf("n    请选择:");
    printf("n    1.知道要修改学生的序号!");
    printf("n    2.知道要修改学生的名字!");                                                                                                             
    printf("n    请输入选择:");
    scanf("%d",&x);
    if(x==1 || x==2)
      break;
    else
      printf("n   输入错误,请重新输入!");
  }
  if(x==1)
  {
    printf("n    请输入要修改学生的序号:");
    scanf("%d",&number);
    while(temp->data.number!=number && temp->next!=NULL)
    {
      temp=temp->next;
    }
    if(temp->data.number==number)
    {
      printf("n     已经找到要修改学生的信息!");
    }
    else
    {
      printf("n    没有要修改学生的序号!");
    }
  }
  else if(x==2)
  {
    printf("n     请输入要修改学生的名字:");
    scanf("%s",name);
    while(strcmp(temp->data.name,name)!=0 && temp->next!=NULL)
    {
      temp=temp->next;
    }
    if(strcmp(temp->data.name,name)==0)
    {
      printf("n     已经找到要修改学生的信息!");
    }
    else
    {
      printf("n     没有要修改学生的姓名!");
    }
  }
  printf("n     ************************");
  printf("n   姓名:%s  序号:%d  成绩:%d  年龄:%d",temp->data.name,temp->data.number,temp->data.score,temp->data.age);
  do{
    printf("n     请选择:");
    printf("n     1.修改序号!");
    printf("n     2.修改名字!");
    printf("n     3.修改成绩!");
    printf("n     4.修改年龄!");
    printf("n     请输入选择:");
    scanf("%d",&x);
  }while(x<1 || x>4);
  if(x==1)
  {
    printf("n     请输入修改后的序号:");
    scanf("%d",&temp->data.number);
  }
  if(x==2)
  {
    printf("n     请输入修改后的名字:");
    scanf("%s",temp->data.name);
  }
  if(x==3)
  {
    printf("n     请输入修改后的成绩:");
    scanf("%d",&temp->data.score);
  }
  if(x==4)
  {
    printf("n     请输入修改后的年龄:");
    scanf("%d",&temp->data.age);
  }

}

void save(LinkList *L)
{
  FILE *fp;
  int i=0;
  LinkList *temp;                                                                                                                                        
  temp=L->next;
  if((fp=fopen("student.txt","a"))==NULL)
  {
    printf("n     无法打开文件!");
    exit(1);
  } 
  while(temp!=NULL)
  {
    i++;
    fprintf(fp,"%d %s %d %d n",temp->data.number,temp->data.name,temp->data.score,temp->data.age);
    printf("n     第%d个已经保存!",i);
    temp=temp->next;
  }
  fclose(fp);
}

void refresh(LinkList *L)
{
  FILE *fp;
  LinkList *node=NULL;                                                          
  LinkList *temp=L->next;
  node=(LinkList *)malloc(sizeof(LinkList));
  if(node==NULL)
  {
    printf("分配普通节点内存出错!");
    exit(1);
  }
  memset(node,0,sizeof(LinkList));  
  fp=fopen("student.txt","r");
  if(fp==NULL)
  {
    printf("n     无法打开文件!");
    exit(1);
  }
  while(!feof(fp))
  {
    fscanf(fp,"%d %s %d %d",&node->data.number,node->data.name,&node->data.score,&node->data.age);
    L->next=node;
    node->next=temp;
    temp=node;
    node=(LinkList *)malloc(sizeof(LinkList));
    if(node==NULL)
    {
      printf("分配普通节点内存出错!");
      exit(1);
    }
    memset(node,0,sizeof(LinkList));
  }                                                                                                                                                      
  printf("n     已经成功刷新学生信息!");
}
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值