C 语言文件操作 ( 学生管理系统 | 插入数据 | 查询数据 | 删除数据 )

Posted 韩曙亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C 语言文件操作 ( 学生管理系统 | 插入数据 | 查询数据 | 删除数据 )相关的知识,希望对你有一定的参考价值。





一、学生管理系统



实现一个简易学生管理系统 , 验证文件操作 ;


1、插入数据


从命令行接收数据 , 放入结构体成员中 , 最后将结构体数据写出到内存中 ;

/*
 * 插入学生数据
 */
int insert()

    // 要写入文件的结构体
    struct student s1 = 0;

    // 打开要写入的文件
    FILE *p = fopen("student.dat", "w");
    // 打开失败直接退出
    if(p == NULL)
        return 0;

    while (1)
    
        // 提示输入学生名字
        printf("input student's name:\\n");
        // 阻塞等待命令行中用户输入学生名字
        scanf("%s", s1.name);

        // 如果用户输入 quit , 则退出循环 , 保存文件
        if(strcmp(s1.name, "quit")==0)
            break;

        // 提示输入某个学生的年龄
        printf("input %s's age:\\n", s1.name);
        // 命令行阻塞等待用户输入学生年龄
        scanf("%d", &s1.age);

        // 将结构体写出到文件中
        fwrite(&s1, 1, sizeof (struct student), p);
    
    // 关闭文件
    fclose(p);
    return 0;


2、查询数据


从命令行中输入要查询的学生信息 , 如果查询全部学生信息 , 则传入 “all” ;

循环从文件中读取单个结构体信息 , 逐个遍历结构体的 name 成员 , 查询是否是要查询的学生姓名 ; 如果是则打印该数据 ;

/*
 * 查询学生数据
 */
int query()

    // 缓存信息用的结构体
    struct student s =  0 ;

    // 要查询的数组
    char name[30] =  0 ;
    // 提示输入要查询的学生名字
    printf("input student's name:");
    // name 数组接收控制台输入的字符串
    scanf("%s", name);

    // 打开文件
    FILE *p = fopen("student.dat", "r");
    // 文件打开失败退出
    if (p == NULL)
        return 0;

    // 使用该变量记录是否查询到学生信息
    int status = 0;
    // 循环读取 student 结构体数据
    // 每次都可以读取到一个学生数据
    // 判断该数据是否是要查询的学生数据
    while(1)
    
        // 从文件中读取一个结构体大小的数据
        fread(&s, 1, sizeof(struct student), p);
        // 判断是否读取到文件末尾, 注意 feof 必须在文件操作之后才能调用
        if (feof(p))
            break;

        // 如果学生名字是 all , 则打印所有学生信息
        if (strcmp(name, "all") == 0)
        
            // 打印学生信息
            printf("name=%s, age=%d\\n", s.name, s.age);
            // 标记信息找到
            status = 1;
        
        else
        
            // 对比本次读取的学生信息是否是要查询的信息
            if (strcmp(name, s.name) == 0)
            
                // 打印要查询的学生信息
                printf("name=%s, age=%d\\n", s.name, s.age);
                // 标记信息找到
                status = 1;
            
        
    

    // 关闭文件
    fclose(p);

    // 如果学生信息没有找到, 打印提示信息
    if (status == 0)
        printf("student %s not found\\n", name);

    return 0;


3、删除数据


将所有的学生数据一次性全部读取出来 ;

然后逐个遍历 , 使用 结构体指针 , 逐个遍历上述全部数据 ;

遍历的同时 , 写出数据 , 如果学生的名字不是要删除的名字 , 则重新写出到文件中 , 否则数据丢弃 , 这样就实现了数据删除操作 ;

/*
 * 删除学生
 */
int delete()

    // 打开学生信息文件
    FILE *p = fopen("student.dat", "r");
    // 如果打开失败, 退出
    if (p == NULL)
        return 0;

    // 获取文件大小 , 将文件指针跳转到文件结尾
    fseek(p, 0, SEEK_END);
    // 获取文件指针位置 , 该位置就是文件大小
    int size = ftell(p);

    // 为学生类型结构体分配堆内存空间, 分配文件大小空间
    struct student *s = malloc(size);

    // 文件指针指向开始位置
    fseek(p, 0, SEEK_SET);

    // 将所有的文件数据读取到堆内存中
    fread(s, 1, size, p);
    // 关闭文件
    fclose(p);

    // 提示要删除的学生名字
    printf("input delete student's name: ");
    // 获取要删除的学生名字
    char name[30] =  0 ;
    // 从命令行接收学生名字
    scanf("%s", name);

    // 统计文件中记录了多少个学生信息
    int n = size / sizeof(struct student);//得到了多少记录数

    // 循环控制变量
    int i;
    // 以写的方式打开文件 , 本次写入文件是覆盖写出文件
    p = fopen("student.dat", "w");
    // 循环遍历结构体数据
    for(i = 0; i < n; i++)
    
        // 学生数据不是要删除的数据, 才能写出到文件中
        if (strcmp(s[i].name, name) != 0)
            // 写出一条学生数据结构体
            fwrite(&s[i], 1, sizeof(struct student), p);
    

    // 关闭文件
    fclose(p);
    // 释放内存中的文件数据内存
    free(s);
    return 0;





二、完整代码



代码示例 :

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

// 存储学生姓名和年龄结构体
struct student

    char name[30];  // 姓名
    int age;        // 年龄
;

/*
 * 插入学生数据
 */
int insert()

    // 要写入文件的结构体
    struct student s1 = 0;

    // 打开要写入的文件
    FILE *p = fopen("student.dat", "w");
    // 打开失败直接退出
    if(p == NULL)
        return 0;

    while (1)
    
        // 提示输入学生名字
        printf("input student's name:\\n");
        // 阻塞等待命令行中用户输入学生名字
        scanf("%s", s1.name);

        // 如果用户输入 quit , 则退出循环 , 保存文件
        if(strcmp(s1.name, "quit")==0)
            break;

        // 提示输入某个学生的年龄
        printf("input %s's age:\\n", s1.name);
        // 命令行阻塞等待用户输入学生年龄
        scanf("%d", &s1.age);

        // 将结构体写出到文件中
        fwrite(&s1, 1, sizeof (struct student), p);
    
    // 关闭文件
    fclose(p);
    return 0;


/*
 * 查询学生数据
 */
int query()

    // 缓存信息用的结构体
    struct student s =  0 ;

    // 要查询的数组
    char name[30] =  0 ;
    // 提示输入要查询的学生名字
    printf("input student's name:");
    // name 数组接收控制台输入的字符串
    scanf("%s", name);

    // 打开文件
    FILE *p = fopen("student.dat", "r");
    // 文件打开失败退出
    if (p == NULL)
        return 0;

    // 使用该变量记录是否查询到学生信息
    int status = 0;
    // 循环读取 student 结构体数据
    // 每次都可以读取到一个学生数据
    // 判断该数据是否是要查询的学生数据
    while(1)
    
        // 从文件中读取一个结构体大小的数据
        fread(&s, 1, sizeof(struct student), p);
        // 判断是否读取到文件末尾, 注意 feof 必须在文件操作之后才能调用
        if (feof(p))
            break;

        // 如果学生名字是 all , 则打印所有学生信息
        if (strcmp(name, "all") == 0)
        
            // 打印学生信息
            printf("name=%s, age=%d\\n", s.name, s.age);
            // 标记信息找到
            status = 1;
        
        else
        
            // 对比本次读取的学生信息是否是要查询的信息
            if (strcmp(name, s.name) == 0)
            
                // 打印要查询的学生信息
                printf("name=%s, age=%d\\n", s.name, s.age);
                // 标记信息找到
                status = 1;
            
        
    

    // 关闭文件
    fclose(p);

    // 如果学生信息没有找到, 打印提示信息
    if (status == 0)
        printf("student %s not found\\n", name);

    return 0;


/*
 * 删除学生
 */
int delete()

    // 打开学生信息文件
    FILE *p = fopen("student.dat", "r");
    // 如果打开失败, 退出
    if (p == NULL)
        return 0;

    // 获取文件大小 , 将文件指针跳转到文件结尾
    fseek(p, 0, SEEK_END);
    // 获取文件指针位置 , 该位置就是文件大小
    int size = ftell(p);

    // 为学生类型结构体分配堆内存空间, 分配文件大小空间
    struct student *s = malloc(size);

    // 文件指针指向开始位置
    fseek(p, 0, SEEK_SET);

    // 将所有的文件数据读取到堆内存中
    fread(s, 1, size, p);
    // 关闭文件
    fclose(p);

    // 提示要删除的学生名字
    printf("input delete student's name: ");
    // 获取要删除的学生名字
    char name[30] =  0 ;
    // 从命令行接收学生名字
    scanf("%s", name);

    // 统计文件中记录了多少个学生信息
    int n = size / sizeof(struct student);//得到了多少记录数

    // 循环控制变量
    int i;
    // 以写的方式打开文件 , 本次写入文件是覆盖写出文件
    p = fopen("student.dat", "w");
    // 循环遍历结构体数据
    for(i = 0; i < n; i++)
    
        // 学生数据不是要删除的数据, 才能写出到文件中
        if (strcmp(s[i].name, name) != 0)
            // 写出一条学生数据结构体
            fwrite(&s[i], 1, sizeof(struct student), p);
    

    // 关闭文件
    fclose(p);
    // 释放内存中的文件数据内存
    free(s);
    return 0;


/*
 * 打印学生管理系统帮助信息
 */
void printf_help()

    printf("help info :\\n");
    printf("i : insert student data\\n");
    printf("q : query student data\\n");
    printf("d : delete student data\\n");



/*
 * 函数入口
 * 参数 i 表示插入数据
 * 参数 q 表示查询数据
 * 参数 d 表示删除数据
 */
int main(int argc, char **args)

    // 判断参数个数是否合法
    if (argc < 2)
        // 提示正确的参数信息
        printf_help();
        return 0;
    

    // 插入数据
    if (strcmp(args[1], "i") == 0)
        insert();

    // 查询数据
    if (strcmp(args[1], "q") == 0)
        query();

    // 删除数据
    if (strcmp(args[1], "d") == 0)
        delete();
    return 0;


编译程序 : 生成 student.exe 可执行文件 ;

gcc main.c -o student


输入错误参数 : 如果输入参数小于 2 个 , 则提示参数信息 ;


插入数据 :

查询数据 :

删除数据 :

以上是关于C 语言文件操作 ( 学生管理系统 | 插入数据 | 查询数据 | 删除数据 )的主要内容,如果未能解决你的问题,请参考以下文章

C 语言文件操作 ( 学生管理系统 | 命令行接收数据填充结构体 | 结构体写出到文件中 | 查询文件中的结构体数据 )

学生信息管理系统(C语言,带文件操作)

用C语言设计一个学生信息查询系统程序

学生信息管理系统C语言编程

C语言数组的删除,插入

c语言学生成绩管理系统