数据结构 study 4: 学生信息管理 读写文件

本文介绍了如何将学生信息结构体插入线性单链表,并实现文件存储、删除与修改功能,涉及插入排序和链表维护。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据结构 study 4: 学生信息管理

学生信息包括:
姓名
学号
性别
年龄
班级
健康状况

每个学生的学生信息,整体作为一个元素,插入一个线性单链表中

之前的 线性单链表中的元素是 一个整形的数据,
现在线性单链表中的元素 是一个结构体。
同时可以将线性单链表中的所有元素,保存到一个文件中去。
(参考高一凡 数据结构)

删除信息 和修改信息,比较重要。
修改信息的时候,因为信息修改了,涉及到重新排序的问题。

问题描述

page48

#define NAMELEN 8 /* 姓名最大长度 */
#define CLASSLEN 4 /* 班级名最大长度 */
struct stud /* 记录的结构 */
{
  char name[NAMELEN+1];  //姓名
  long num;
  char sex;
  int age;
  char Class[CLASSLEN+1];//班级名称
  int health;
};
struct stud student[N]={{"王小林",790631,'m',18,"计91",0},
                        {"陈红",790632,'f',20,"计91",1},
                        {"刘建平",790633,'m',21,"计91",0},
                        {"张立立",790634,'m',17,"计91",2}}; /* 表的初始记录 */
char sta[3][9]={"健康  ","一般  ","神经衰弱"}; /* 健康状况(3类) */
简单的例子:
/* c1.h (程序名) */
#include<string.h>
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<limits.h> /* INT_MAX等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<stdlib.h> /* atoi() */
#include <sys/io.h> /* eof() */
#include<math.h> /* floor(),ceil(),abs() */

#include<pthread.h> /* exit() */
/* 函数结果状态代码 */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
/* #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行 */
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */

#define NAMELEN 16 /* 姓名最大长度 */     //8
#define CLASSLEN 16 /* 班级名最大长度 */  //4
struct stud /* 记录的结构 */
{
  char name[NAMELEN];
  long num;
  char sex;
  int age;
  char Class[CLASSLEN];
  int health;
};
//{"张立立",790634,'m',17,"计91",2}



typedef struct stud ElemType; /* 链表结点元素类型为结构体 */

typedef struct LNode {
    ElemType data;
    struct LNode *next ;
}LNode, *LinkList,*LinkNode ;


int create_list(LinkList *L)
{
    *L = (LinkList)malloc(sizeof(struct LNode));

    if(!(*L)){

        exit(1);
    }

    (*L)->next = NULL ;
    
    return 0 ;
}


/*
  i 从1这个位置开始
*/

int insert_list(LinkList L,int i ,ElemType e)
{
    LinkNode p ; 
    LinkNode s ;
    int j =0 ;

    p = L ;

    if(i <1){

        return -1 ;
    }

    while(p &&(j<i-1))
    {
        p = p->next ;
        j++ ;

    }

    if((!p)||(j<(i-1))){

        return  -1 ;
    }    


    s = (LinkNode)malloc(sizeof(struct LNode));
    if(!s){
        printf("malloc error\n");
        exit(1);
    }

    s->next = NULL;

    s->data = e ;
    s->next = p->next ;

    p->next = s;

    return OK ;
}


void visit(ElemType data)
{
    printf("%s \n", data.name);
}

int traverse_list(LinkList L,void (*visit)(ElemType ))
{
    LinkNode p = L->next ;

    while(p){

        visit(p->data);

        p = p->next;

        
    }
    
    printf("\n");

    return OK ;    
}

#define N 4 /* student记录的个数 */

int main()
{
    LinkList L;
    int i ;
    ElemType data ;

    
    
    struct stud student[N]={{"王小林",790631,'m',18,"计91",0},
                            {"陈红",790632,'f',20,"计91",1},
                            {"刘建平",790633,'m',21,"计91",0},
                            {"张立立",790634,'m',17,"计91",2}}; /* 表的初始记录 */


    printf("sizeof(\"刘建平\") = %d\n",strlen("刘建平"));
    printf("sizeof(\"计91\") = %d\n",strlen("计91"));  
    printf("Hello World NULL = %d\n",NULL); 
    
    create_list(&L);


    for(i=1;i <= N; i++){

        insert_list(L,i,student[i-1]);
    }


    traverse_list(L, visit);    


   
}



运行效果:
sizeof("刘建平") = 9
sizeof("计91") = 5
Hello World NULL = 0
王小林
陈红
刘建平
张立立

学生信息 存放到文件中去
/* c1.h (程序名) */
#include<string.h>
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<limits.h> /* INT_MAX等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<stdlib.h> /* atoi() */
#include <sys/io.h> /* eof() */
#include<math.h> /* floor(),ceil(),abs() */

#include<pthread.h> /* exit() */
/* 函数结果状态代码 */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
/* #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行 */
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */

#define NAMELEN 16 /* 姓名最大长度 */     //8
#define CLASSLEN 16 /* 班级名最大长度 */  //4
struct stud /* 记录的结构 */
{
  char name[NAMELEN];
  long num;
  char sex;
  int age;
  char Class[CLASSLEN];
  int health;
};
//{"张立立",790634,'m',17,"计91",2}

FILE *fp;
char sta[3][13]={"健康  ","一般  ","神经衰弱"}; /* 健康状况(3类) */


typedef struct stud ElemType; /* 链表结点元素类型为结构体 */

typedef struct LNode {
    ElemType data;
    struct LNode *next ;
}LNode, *LinkList,*LinkNode ;


int create_list(LinkList *L)
{
    *L = (LinkList)malloc(sizeof(struct LNode));

    if(!(*L)){

        exit(1);
    }

    (*L)->next = NULL ;
    
    return 0 ;
}


/*
  i 从1这个位置开始
*/

int insert_list(LinkList L,int i ,ElemType e)
{
    LinkNode p ; 
    LinkNode s ;
    int j =0 ;

    p = L ;

    if(i <1){

        return -1 ;
    }

    while(p &&(j<i-1))
    {
        p = p->next ;
        j++ ;

    }

    if((!p)||(j<(i-1))){

        return  -1 ;
    }    


    s = (LinkNode)malloc(sizeof(struct LNode));
    if(!s){
        printf("malloc error\n");
        exit(1);
    }

    s->next = NULL;

    s->data = e ;
    s->next = p->next ;

    p->next = s;

    return OK ;
}


void InsertAscend(LinkList L,ElemType e) /* 此函数是由bo2-9.c中的同名函数改写 */
{ /* 按学号非降序插入 */
  LinkList q=L,p=L->next;
  while(p&&e.num>p->data.num)
  {
    q=p;
    p=p->next;
  }
  q->next=(LinkList)malloc(sizeof(struct LNode)); /* 插在q后 */
  q->next->data=e;
  q->next->next=p;
}

Status ReadFromFile(struct stud *e)
{ /* 由fp指定的文件读取结点信息到e */
  int i;
  i=fread(e,sizeof(struct stud),1,fp);
  if(i==1) /* 读取文件成功 */
    return OK;
  else
    return ERROR;
}



void WriteToFile(struct stud e)
{ /* 将结点信息写入fp指定的文件 */
  fwrite(&e,sizeof(struct stud),1,fp);
}


void Print(struct stud e)
{ /* 显示记录e的内容 */
  printf("%-8s %6ld",e.name,e.num);
  if(e.sex=='m')
    printf(" 男");
  else
    printf(" 女");
  printf("%5d  %-4s",e.age,e.Class);
  printf("%13s\n",sta[e.health]);
}



void visit(ElemType data)
{
    printf("%s \n", data.name);
}

int traverse_list(LinkList L,void (*visit)(ElemType ))
{
    LinkNode p = L->next ;

    while(p){

        visit(p->data);

        p = p->next;

        
    }
    
    printf("\n");

    return OK ;    
}

#define N 4 /* student记录的个数 */

int main()
{
    LinkList L;
    int i ;
    ElemType data ;
    int flag =1;
    ElemType e;
    char filename[13] ="table.txt";
    
    
    struct stud student[N]={{"王小林",790631,'m',18,"计91",0},
                            {"陈红",790632,'f',20,"计91",1},
                            {"刘建平",790633,'m',21,"计91",0},
                            {"张立立",790634,'m',17,"计91",2}}; /* 表的初始记录 */


    printf("sizeof(\"刘建平\") = %d\n",strlen("刘建平"));
    printf("sizeof(\"计91\") = %d\n",strlen("计91"));  
    printf("Hello World NULL = %d\n",NULL); 
    printf("sizeof(\"神经衰弱\") = %d\n", sizeof("神经衰弱"));
    
    create_list(&L);


    for(i=1;i <= N; i++){

        insert_list(L,i,student[i-1]);
    }


    traverse_list(L, visit);    


    
    while(flag)
    {

        printf("\n");
        
        /*
         30(黑色)、31(红色)、32(绿色)、 33(黄色)、
         34(蓝色)、35(洋红)、36(青色)、37(白色)
        */
        
        printf("\033[0;36;40m");
        printf("1:将结构体数组student中的记录按学号非降序插入链表\n");
        printf("2:将文件中的记录按学号非降序插入链表\n");
        printf("3:键盘输入新记录,并将其按学号非降序插入链表\n");
        printf("4:删除链表中第一个有给定学号的记录\n");
        printf("5:删除链表中第一个有给定姓名的记录\n");
        printf("6:修改链表中第一个有给定学号的记录\n");
        printf("7:修改链表中第一个有给定姓名的记录\n");
        printf("8:查找链表中第一个有给定学号的记录\n");
        printf("9:查找链表中第一个有给定姓名的记录\n");
        printf("10:显示所有记录  \n");
        printf("11:将链表中的所有记录存入文件\n");
        printf("12:结束\n");
        printf("\033[0m");
        printf("\n");
        printf("请选择操作命令: ");
        scanf("%d",&i);

        switch(i){
       
           case 2:                
                   if((fp=fopen(filename,"rb"))==NULL)
                   {
                        printf("打开文件失败!\n");
                   }
                   else
                   {
                     while(ReadFromFile(&e)){
                       InsertAscend(L,e);
                     }
                     fclose(fp);
                   }
                   break;    

            case 10:
                   printf("姓名    学号 性别 年龄 班级 健康状况\n");
                   traverse_list(L,Print);
                   break;               
            case 11:                
                    if((fp=fopen(filename,"wb"))==NULL){
                      printf("打开文件失败!\n");
                    }
                    else{
                      traverse_list(L,WriteToFile);
                    }
                    fclose(fp);
                    break;
                    
            case 12:
                flag = 0 ;
                break ;
        }    
    }
    
}



运行效果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值