美文网首页
C-学生管理系统

C-学生管理系统

作者: 小石头呢 | 来源:发表于2019-08-08 23:54 被阅读0次

    目的

    通过完成一个简单的学生管理系统,达到掌握文件操作,动态分配内存,单链表的作用

    技术

    文件操作,动态分配内存,单链表

    如何使用

    1.文件操作

    打开文件函数:

    FILE* fopen(const char* fileName,const char* openMode);
    
    • fileName是文件地址,openMode是打开方式
    • r:是读一个已有的文件
    • w:是写,没有文件会创建,有了会将内容清空,从头开始写
    • a:和w类似,但是在文本末尾追加写
    • r+,w+,a+:可读可写

    关闭文件函数:

    int fclose(FILE* pointerOnFile);
    

    写、读数据块数据到文件函数:

    fwrite(buffer,size,count,fp);
    
     fread(buffer,size,count,fp);
    
    • buffer -- 是一个指针,在fread函数中,它表示存放输入数据的首地址。在fwrite函数中,它表示存放输出数据的首地址。
    • size -- 表示数据库的字节数
    • count -- 表示要读写的数据库块数
    • fp -- 表示文件指针

    获得当前游标位置的函数:

    long ftell(FILE* pointerOnFile);
    

    游标移动函数:

    int fseek(FILE* pointerOnFile, long move, int origin);
    
    • 使游标在文件(pointerOnFile指针所指)中从位置(origin所指)开始移动一段距离(move所指)

    • move:可以是一个正整数,表明向前移动;0,不移动;负整数,表明回退

    • origin:它有三个取值,SEEK_SET:文件开始处,SEEK_CUR:游标当前所处位置,SEEK_END:文件末尾

    
    //加载数据
    void loadData(Student *pTemp){
    
        //打开文件
        FILE *fp = fopen(FILE_PATH,"r");
    
        //循环读取数据
        int SEEK_MOVE = 0;
        while (1){
    
            //准备一个结构体 保存数据
            Student *pStu = (Student *)malloc(1 * sizeof(Student));
    
            //移动游标
            fseek(fp,SEEK_MOVE,SEEK_SET);
    
            //读取数据
            int result = fread(pStu,sizeof(Student),1,fp);
            //如果读到文件末尾
            if (result == 0){
                break;
            }
            //printf("id:%d 姓名:%s 成绩:%f \n",pStu->s_ID,pStu->name,pStu->score);
    
            //链接
            pTemp->next = pStu;
            pTemp = pTemp->next;
    
            //为下次移动确定位置
            SEEK_MOVE = ftell(fp);
        }
    
        //关闭文件
        fclose(fp);
    
        printf("加载数据成功\n");
    }
    

    上面的函数主要用来读取存放在文件里面的一个个Student类型的结构体,并将它们依次链接到头结点之后。

    2.动态分配内存

    • 需要导入<stdlib.h>头文件,才可以调用malloc,realloc,free函数

    • void *malloc(int num);函数在堆区分配一定的内存。

    • void *realloc(void *address, int newsize);在malloc分配的基础上重新分配内存。

    • void free(void *address);释放掉手动分配的内存。

    • void *类型表示未确定类型的指针,可以通过类型转换强制转换为任何其它类型的指针。

    Student *pTemp = (Student *)malloc(1 * sizeof(Student));
    

    上面的例子就是动态分配了一个Student结构体类型的变量。

    3.单链表

    链表的基本结构
    头结点初始化情况
    //初始化一个头结点
    void initHeader(Student **pHeader){
        //动态分配内存
        Student *pTemp = (Student *)malloc(1 * sizeof(Student));
    
        //初始化
        pTemp->next = NULL;
    
        //改变外部的值
        *pHeader = pTemp;
    }
    

    上面函数的功能是得到一个头结点。

    尾插一个结点
    void insert(Student *pTemp){
        //准备一个结构体 保存数据
        Student *pStu = (Student *)malloc(1 * sizeof(Student));
        pStu->next = NULL;
    
        //提示用户输入
        printf("请输入姓名:");
        scanf("%s",pStu->name);
        printf("请输入成绩:");
        scanf("%f",&(pStu->score));
    
        //自动编号
        int count = 0;
        while (pTemp->next != NULL){
            pTemp = pTemp->next;
            count++;
        }
        pStu->s_ID = count+1;
    
        //插入
        pTemp->next = pS
    }
    

    上面函数的功能是在链表的最后添加一个结点。

    删除一个结点



    //删除数据
    void deleteInfo(Student *pTemp){
    
        printf("请输入要删除的学生ID:");
        int id = 0;
        scanf("%d",&id);
        
        //找到要删除的那个结点的上一个结点
        while (pTemp->next->s_ID != id ){
    
            //推到下一个结点
            pTemp = pTemp->next;
    
            if (pTemp->next == NULL){
                printf("没有该学生\n");
                return;
            }
        }
    
        //更改链接关系
        Student *temp = pTemp->next;
        pTemp->next = temp->next;
    
        //释放内存
        free(temp);
    
        printf("删除数据成功\n");
    }
    

    上面函数的功能是根据结点数据域的值删除对应的结点。

    修改某个结点的数据域的值
    //修改数据
    void updateInfo(Student *pTemp){
        printf("请输入要修改的学生ID:");
        int id = 0;
        scanf("%d",&id);
    
        //找到第一个数据结点
        pTemp = pTemp->next;
    
        //找到要删除的那个结点
        while (pTemp->s_ID != id ){
            //推到下一个结点
            pTemp = pTemp->next;
    
            if (pTemp == NULL){
                printf("没有该学生\n");
                return;
            }
        }
    
        printf("请输入修改后的学生名字:");
        scanf("%s",pTemp->name);
        printf("请输入修改后的学生分数:");
        scanf("%f",&pTemp->score);
    
        printf("修改数据成功\n");
    }
    

    上面函数的功能是根据结点数据域的值找到对应的结点,修改其数据域的值。

    具体使用

    #include <stdio.h>
    #include <stdlib.h>
    
    //文件路径
    #define FILE_PATH "C:/Users/a2867/Desktop/S_T.txt"
    
    //定义一个学生的结构体结点
    typedef struct Node{
        char name[10];
        int s_ID;
        float score;
        struct Node *next;
    }Student;
    
    //初始化一个头结点
    void initHeader(Student **pHeader);
    
    //操作界面
    void showMenu();
    
    //获取操作序列
    int getChoice();
    
    //加载数据
    void loadData(Student *pTemp);
    
    //退出程序-保存数据
    void exitS_T(int status,Student *pTemp);
    
    //插入数据
    void insert(Student *pTemp);
    
    //查询数据
    void querry(Student *pTemp);
    
    //删除数据
    void deleteInfo(Student *pTemp);
    
    //修改数据
    void updateInfo(Student *pTemp);
    
    
    #include "S_T.h"
    
    int main(){
    
        //定义一个指针 记录头结点
        Student *pHeader = NULL;
    
        //初始化头结点
        initHeader(&pHeader);
    
        //加载数据
        loadData(pHeader);
        
        //操作界面
        int choice = 0;
        while (1){
    
            //显示操作
            showMenu();
    
            //选择
            choice = getChoice();
    
            //具体操作
            switch (choice){
    
                case 1:
                    //查询
                    querry(pHeader);
                    break;
                case 2:
                    //删除
                    deleteInfo(pHeader);
                    break;
                case 3:
                    //修改
                    updateInfo(pHeader);
                    break;
                case 4:
                    //插入
                    insert(pHeader);
                    printf("插入成功!\n");
                    break;
                default:
                    exitS_T(EXIT_SUCCESS,pHeader);
                    break;
            }
    
            //清除输入缓冲区
            fflush(stdin);
            getchar();
    
            //清屏
            system("CLS");
    
        }
    
        return 0;
    }
    
    //初始化一个头结点
    void initHeader(Student **pHeader){
        //动态分配内存
        Student *pTemp = (Student *)malloc(1 * sizeof(Student));
        //初始化
        pTemp->next = NULL;
        //改变外部的值
        *pHeader = pTemp;
    }
    
    //操作界面
    void showMenu(){
        printf("************\n");
        printf("1.查询\n");
        printf("2.删除\n");
        printf("3.更改\n");
        printf("4.插入\n");
        printf("5.退出\n");
        printf("************\n");
    }
    
    //获取操作序列
    int getChoice(){
    
        int choice;
    
        printf("请选择操作:");
        scanf("%d", &choice);
        
        return choice;
    }
    
    //加载数据
    void loadData(Student *pTemp){
    
        //打开文件
        FILE *fp = fopen(FILE_PATH,"r");
    
        //循环读取数据
        int SEEK_MOVE = 0;
        while (1){
    
            //准备一个结构体 保存数据
            Student *pStu = (Student *)malloc(1 * sizeof(Student));
    
            //移动游标
            fseek(fp,SEEK_MOVE,SEEK_SET);
    
            //读取数据
            int result = fread(pStu,sizeof(Student),1,fp);
            //如果读到文件末尾
            if (result == 0){
                break;
            }
            //printf("id:%d 姓名:%s 成绩:%f \n",pStu->s_ID,pStu->name,pStu->score);
    
            //链接
            pTemp->next = pStu;
            pTemp = pTemp->next;
    
            //为下次移动确定位置
            SEEK_MOVE = ftell(fp);
        }
    
        //关闭文件
        fclose(fp);
    
        printf("加载数据成功\n");
    }
    
    //退出程序
    void exitS_T(int status,Student *pTemp){
        
        //创建、打开文件,从头写
        FILE *fp = fopen(FILE_PATH,"w");
    
        //保存数据
        while (pTemp->next){
    
            //找到下一个
            pTemp = pTemp->next;
    
            //保存当前节点结构体到文件中
            fwrite(pTemp,sizeof(Student),1,fp);
            //printf("id:%d 姓名:%s 成绩:%f \n",pTemp->s_ID,pTemp->name,pTemp->score);  
        }
    
        //关闭文件
        fclose(fp);
    
        printf("保存数据成功 感谢你的使用\n");
        
        //退出
        exit(status);
    }
    
    //插入数据
    void insert(Student *pTemp){
        //准备一个结构体 保存数据
        Student *pStu = (Student *)malloc(1 * sizeof(Student));
        pStu->next = NULL;
    
        //提示用户输入
        printf("请输入姓名:");
        scanf("%s",pStu->name);
        printf("请输入成绩:");
        scanf("%f",&(pStu->score));
    
        //自动编号
        int count = 0;
        while (pTemp->next != NULL){
            pTemp = pTemp->next;
            count++;
        }
        pStu->s_ID = count+1;
    
        //插入
        pTemp->next = pStu;
    }
    
    //查询数据
    void querry(Student *pTemp){
    
        //找到第一个数据结点
        pTemp = pTemp->next;
    
        //循环打印数据
        printf("         学生数据\n");
        while (pTemp != NULL){
    
            //输出
            printf("ID:%d ", pTemp->s_ID);
            printf("name:%s ", pTemp->name);
            printf("score:%.1f",pTemp->score);
            printf("\n");
    
            //下一个
            pTemp = pTemp->next;
        }
    }
    
    //删除数据
    void deleteInfo(Student *pTemp){
    
        printf("请输入要删除的学生ID:");
        int id = 0;
        scanf("%d",&id);
        
        //找到要删除的那个结点的上一个结点
        while (pTemp->next->s_ID != id ){
    
            //推到下一个结点
            pTemp = pTemp->next;
    
            if (pTemp->next == NULL){
                printf("没有该学生\n");
                return;
            }
        }
    
        //更改链接关系
        Student *temp = pTemp->next;
        pTemp->next = temp->next;
    
        //释放内存
        free(temp);
    
        printf("删除数据成功\n");
    }
    
    //修改数据
    void updateInfo(Student *pTemp){
        printf("请输入要修改的学生ID:");
        int id = 0;
        scanf("%d",&id);
    
        //找到第一个数据结点
        pTemp = pTemp->next;
    
        //找到要删除的那个结点
        while (pTemp->s_ID != id ){
            //推到下一个结点
            pTemp = pTemp->next;
    
            if (pTemp == NULL){
                printf("没有该学生\n");
                return;
            }
        }
    
        printf("请输入修改后的学生名字:");
        scanf("%s",pTemp->name);
        printf("请输入修改后的学生分数:");
        scanf("%f",&pTemp->score);
    
        printf("修改数据成功\n");
    }
    

    运行结果

    1.查询数据,插入一条数据,保存数据

    2.查询数据(检查上次插入的数据是否保存),删除ID为4的数据,修改ID为3的数据,保存数据

    3.查询数据(检查上次的删除,上次的修改是否保存)

    相关文章

      网友评论

          本文标题:C-学生管理系统

          本文链接:https://www.haomeiwen.com/subject/oisydctx.html