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

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

文章目录

一、学生管理系统

1、插入数据

2、查询数据

3、删除数据

二、完整代码





一、学生管理系统


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



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

image.png


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


image.png

插入数据 :

image.png



查询数据 :


image.png


删除数据 :


image.png

目录
相关文章
|
15天前
|
Linux C语言
C语言获取文件长度
C语言获取文件长度
|
30天前
|
安全 算法 程序员
【C/C++ 文件操作】深入理解C语言中的文件锁定机制
【C/C++ 文件操作】深入理解C语言中的文件锁定机制
33 0
|
1月前
|
C语言
C语言对文件的输入输出
C语言对文件的输入输出
17 0
C4.
|
1月前
|
存储 程序员 数据库
C语言顺序读写数据文件
C语言顺序读写数据文件
C4.
15 0
|
1月前
|
存储 C语言
C语言-打开与关闭文件
C语言-打开与关闭文件
21 1
|
5月前
|
存储 Linux C语言
24 C语言 - 文件读写
24 C语言 - 文件读写
39 0
|
6月前
|
存储 编解码 C语言
【c语言】通讯录(动态版+文件+背景音乐)含源码
【c语言】通讯录(动态版+文件+背景音乐)含源码
64 0
|
6月前
|
存储 测试技术 编译器
文件操作【fopen/fclose/fputs/fgets】【C语言/进阶】
文件操作【fopen/fclose/fputs/fgets】【C语言/进阶】
66 0
|
6月前
|
C语言
C语言——通讯录详解(文件版)
C语言——通讯录详解(文件版)
|
1月前
|
存储 程序员 Linux
6.C语言:用fopen函数关闭数据文件
6.C语言:用fopen函数关闭数据文件
20 1