【C语言】:学生管理系统(多文件版)

一、文件框架

二、Data

data.txt

三、Inc

1. list.h

学生结构体

复制代码
#ifndef __LIST_H__
#define __LIST_H__

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

#define MAX_LEN 20

// 学生信息结构体
typedef struct
{
    // 登录用
    char user_name[128]; // 账号
    char password[128];  // 密码
    // 学生信息
    char name[128]; // 学生姓名
    char sex[5];    // 学生性别
    int id;         // 学生id
    int age;        // 学生年龄
    int soc;        // 学生成绩
} stu_user;

顺序表结构体

复制代码
// 顺序表结构体
typedef struct list_str
{
    // 信息
    stu_user data[MAX_LEN];
    // 长度
    int len;
} list_str;

一些关于list功能函数声明...

2. file.h

复制代码
#ifndef __FILE_H__
#define __FILE_H__

#include <stdio.h>
#include <string.h>
#include "list.h"

// 保存用户数据
#define FILE_NAME "./Data/data.txt"

// 更新文件 写入文件
void file_updata_file(list_str *L);

// 更新顺序表
void file_updata_list(list_str *L);

#endif

3. main.h

复制代码
#ifndef __MAIN_H__
#define __MAIN_H__

// 添加头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


// 添加库文件
#include "file.h"
#include "list.h"

#endif

四、Src

1. file.c

更新顺序表

复制代码
#include "file.h"

// 更新文件  写入文件
void file_updata_file(list_str *L)
{
    // 安全判定
    if (NULL == L)
    {
        printf("表为空\n");
        exit(-1);
    }

    // 打开文件
    FILE *fp = fopen(FILE_NAME, "w");
    if (NULL == fp)
    {
        printf("文件打开失败\n");
        exit(-1);
    }

    // 写入文件
    for (size_t i = 0; i < L->len; i++)
    {
        fprintf(fp, "%s\t%s\t%s\t%s\t%d\t%d\t%d\n",
                L->data[i].user_name, L->data[i].password,
                L->data[i].name, L->data[i].sex, L->data[i].id,
                L->data[i].age, L->data[i].soc);
    }
}

// 更新顺序表
void file_updata_list(list_str *L)
{
    // 安全判定
    if (NULL == L)
    {
        printf("表为空\n");
        exit(-1);
    }

    // 打开文件
    FILE *fp = fopen(FILE_NAME, "r+");
    if (NULL == fp)
    {
        printf("文件打开失败\n");
        exit(-1);
    }

    // 让文件流回到开头
    fseek(fp, 0, SEEK_SET);

    // 获取文件行数
    int len = 0;
    char ch = 0;

    // EOF 为 文件结尾
    while (EOF != (ch = fgetc(fp)))
    {
        if ('\n' == ch)
        {
            len++;
        }
    }

    // 让文件流回到开头
    fseek(fp, 0, SEEK_SET);

    // 读取文件到顺序表
    stu_user s1;
    for (size_t i = 0; i < len; i++)
    {
        fscanf(fp, "%s\t%s\t%s\t%s\t%d\t%d\t%d\n",
               s1.user_name, s1.password,
               s1.name, s1.sex, &s1.id,
               &s1.age, &s1.soc);

        // 插入到表中
        list_add(L, s1);
    }

    // 关闭文件
    fclose(fp);
}

2. list.c

复制代码
#include "list.h"

/********************************** 登录 **********************************/
// 学生登录
bool Student_log_in(list_str *L, int *index)
{

    printf("欢迎来到学生登录界面\n");
    // 声明两个字符串
    char user[128];
    char pass[128];

    while (1)
    {
        // 清空字符串
        memset(user, 0, sizeof(user));
        memset(pass, 0, sizeof(pass));
        // 用户输入
        printf("请输入账号:");
        scanf("%s", user);
        printf("请输入密码:");
        scanf("%s", pass);
        // 循环判定
        for (size_t i = 0; i < L->len; i++)
        {
            if (!strcmp(user, L->data[i].user_name))
            {
                if (!strcmp(pass, L->data[i].password))
                {
                    *index = i;
                    return true;
                }
            }
        }
        printf("登录失败,请重新登录!\n");
    }
}

// 老师登录
bool Teacher_log_in(list_str *L)
{
    system("clear");
    printf("欢迎来到老师登录界面\n");
    // 声明两个字符串
    char user[128];
    char pass[128];

    while (1)
    {
        // 清空字符串
        memset(user, 0, sizeof(user));
        memset(pass, 0, sizeof(pass));
        // 用户输入
        printf("请输入账号:");
        scanf("%s", user);
        printf("请输入密码:");
        scanf("%s", pass);
        // 循环判定
        for (size_t i = 0; i < L->len; i++)
        {
            if (!strcmp(user, L->data[i].user_name))
            {
                if (!strcmp(pass, L->data[i].password))
                {
                    return true;
                }
            }
        }
        printf("登录失败,请重新登录!\n");
    }
}

// 初始化
void list_init(list_str **L)
{
    // 创建动态内存
    (*L) = (list_str *)malloc(sizeof(list_str));
    if (NULL == (*L))
    {
        printf("创建失败\n");
        exit(-1);
    }

    // 初始化数据
    (*L)->len = 0;

    return;
}


// 增
bool list_add(list_str *L, stu_user data)
{
    // 判定是否为空
    if (NULL == L)
    {
        printf("传入顺序表为空\n");
        exit(-1);
    }

    // 是否越界
    if (MAX_LEN <= L->len)
    {
        printf("学生已经满了\n");
        return false;
    }

    // 插入操作
    L->data[L->len] = data;

    // 迭代长度
    L->len++;
}

// 增 从终端输入
bool list_add_in(list_str *L)
{
    system("clear");
    list_printf(L);
    // 判定是否为空
    if (NULL == L)
    {
        printf("传入顺序表为空\n");
        exit(-1);
    }

    // 是否越界
    if (MAX_LEN <= L->len)
    {
        printf("学生已经满了\n");
        return false;
    }

    stu_user newStudent;
    char name[128];
    char sex[5];
    int flag = 0;
    printf("请输入你要添加学生的信息:\n");

    printf("姓名:");
    scanf("%s", newStudent.name);

    printf("性别:");
    scanf("%s", newStudent.sex);

    while (1)
    {
        int add_id;
        printf("id:");
        scanf("%d", &add_id);
        for (int i = 0; i < L->len; i++)
        {
            if (add_id == L->data[i].id)
            {
                flag = 1;
                break;
            }
        }
        if (1 == flag)
        {
            printf("你输入的id已重复,请重新输入");
        }
    }

    printf("年龄:");
    scanf("%d", &newStudent.age);

    printf("成绩:");
    scanf("%d", &newStudent.soc);

    printf("密码:");
    scanf("%s", newStudent.password);

    strcpy(newStudent.user_name, newStudent.name);

    // 插入操作
    L->data[L->len] = newStudent;

    // 迭代长度
    L->len++;

    printf("添加成功!\n");

    list_printf(L);
}

// 尾删
bool list_del(list_str *L)
{
    system("clear");
    // 判定是否为空
    if (NULL == L)
    {
        printf("传入顺序表为空\n");
        exit(-1);
    }

    // 是否没有学生了
    if (-1 >= L->len)
    {
        printf("学生已经满了\n");
        return false;
    }

    // 删除尾部学生
    L->len--;

    printf("删除成功!\n");
    list_printf(L);
}

// 老师改  姓名....
bool list_Teacher_alter(list_str *L)
{
    int op;
    char user_name[128]; // 账号
    char password[128];  // 密码
    char name[128];      // 学生姓名
    char sex[5];         // 学生性别
    int find_id;         // 查找学生id
    int age;             // 学生年龄
    int soc;             // 学生成绩

    system("clear");
    list_printf(L);
    printf("请输入你要修改的id:");
    scanf("%d", &find_id);
    printf("请输入你要修改的信息:\n");
    printf("1.账号\n2.密码\n3.姓名\n4.性别\n5.年龄\n6.成绩\n7.退出修改\n");

    while (1)
    {
        scanf("%d", &op);
        switch (op)
        {
        case 1:
            scanf("%s", L->data[find_id].user_name);
            break;
        case 2:
            scanf("%s", L->data[find_id].user_name);
            break;
        case 3:
            scanf("%s", L->data[find_id].name);
            break;
        case 4:
            scanf("%s", L->data[find_id].sex);
            break;
        case 5:
            scanf("%d", &L->data[find_id].age);
            break;
        case 6:
            scanf("%d", &L->data[find_id].soc);
            break;
        default:
            break;
        }
        printf("是否继续修改,是输入1,否输入0\n");
        scanf("%d", &op);
        if (0 == op)
            break;
    }
    printf("账号\t密码\t姓名\t性别\tid\t年龄\t成绩\n");
    printf("%s\t%s\t%s\t%s\t%d\t%d\t%d\n",
           L->data[find_id].user_name, L->data[find_id].password,
           L->data[find_id].name, L->data[find_id].sex, L->data[find_id].id,
           L->data[find_id].age, L->data[find_id].soc);
    printf("修改成功!\n");
}

// 老师查
bool list_Teacher_find(list_str *L)
{
    system("clear");
    int find_id;
    printf("请输入你要查找的id:");
    scanf("%d", &find_id);
    printf("账号\t密码\t姓名\t性别\tid\t年龄\t成绩\n");
    printf("%s\t%s\t%s\t%s\t%d\t%d\t%d\n",
           L->data[find_id].user_name, L->data[find_id].password,
           L->data[find_id].name,L->data[find_id].sex, L->data[find_id].id,
           L->data[find_id].age, L->data[find_id].soc);
    printf("查找成功!\n");
}

// 学生查  查自己
bool list_Student_find(list_str *L, stu_user data)
{
    system("clear");
    printf("账号\t密码\t姓名\t性别\tid\t年龄\t成绩\n");
    printf("%s\t%s\t%s\t%s\t%d\t%d\t%d\n",
        data.user_name, data.password,data.name, data.name, data.id,data.age, data.soc);
    printf("查找成功!\n");
}

// 成绩排序
bool list_sort(list_str *L)
{
    for (int i = 0; i < L->len; i++)
    {
        for (int j = 0; j < j - i - 1; i++)
        {
            if (L->data[j].soc > L->data[j + 1].soc)
            {
                int t = L->data[j].soc;
                L->data[j].soc = L->data[j + 1].soc;
                L->data[j + 1].soc = t;
            }
        }
    }
}

// 遍历程序
void list_printf(list_str *L)
{
    if (NULL == L)
    {
        printf("传入顺序表为空\n");
        exit(-1);
    }

    printf("账号\t密码\t姓名\t性别\tid\t年龄\t成绩\n");
    for (size_t i = 0; i < L->len; i++)
    {
        printf("%s\t%s\t%s\t%s\t%d\t%d\t%d\n",
               L->data[i].user_name, L->data[i].password,
               L->data[i].name, L->data[i].sex, L->data[i].id,
               L->data[i].age, L->data[i].soc);
    }
}

// 释放顺序表
void list_free(list_str **L)
{
    if (NULL == (*L))
    {
        printf("传入顺序表为空\n");
        exit(-1);
    }

    free(*L);
    *L = NULL;
}

// 九九乘法表
void nine_nine()
{
    system("clear");
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= i; j++)
        {
            printf("%d * %d = %d\t", j, i, j * i);
        }
        printf("\n");
    }
}

// 清屏
void clean_screen()
{
    system("clear");
}

// 猜数字
void guess_num()
{
    system("clear");
    int val;
    val = (time(NULL)) % 100;

    int max_val = 99;
    int min_val = 0;
    int data;
    while (1)
    {
        printf("请输入你要猜的数:");
        scanf("%d", &data);

        if (data > val)
        {
            if (data > max_val)
            {
                printf("输入数据违规,请输入数据:%d ~ %d\n", min_val, max_val);
            }
            else
            {
                max_val = data;
                printf("输入数据大了,请输入数据:%d ~ %d\n", min_val, max_val);
            }
        }

        if (data < val)
        {
            if (data < min_val)
            {
                printf("输入数据违规,请输入数据:%d ~ %d\n", min_val, max_val);
            }
            else
            {
                min_val = data;
                printf("输入数据小了,请输入数据:%d ~ %d\n", min_val, max_val);
            }
        }
        if (data == val)
        {
            printf("恭喜你!!!猜对了\n");
            break;
        }
    }
}

// 计算器
// 加
int add(int data1, int data2)
{
    return data1 + data2;
}

// 减
int subtract(int data1, int data2)
{
    return data1 - data2;
}

// 乘
int multiply(int data1, int data2)
{
    return data1 * data2;
}

// 除
int divide(int data1, int data2)
{
    return data1 / data2;
}

// 回调函数
typedef int (*count_func)(int, int);

void counter()
{
    system("clear");
    count_func func[4];
    func[0] = add;
    func[1] = subtract;
    func[2] = multiply;
    func[3] = divide;

    int data1, data2;
    char ch;
    printf("请输入你要输入的算式:\n");
    scanf("%d %c %d", &data1, &ch, &data2);

    switch (ch)
    {
    case '+':
        printf("%d %c %d = %d\n", data1, ch, data2, func[0](data1, data2));
        break;
    case '-':
        printf("%d %c %d = %d\n", data1, ch, data2, func[1](data1, data2));
        break;
    case '*':
        printf("%d %c %d = %d\n", data1, ch, data2, func[2](data1, data2));
        break;
    case '/':
        printf("%d %c %d = %d\n", data1, ch, data2, func[3](data1, data2));
        break;
    default:
        break;
    }
}

3. main.c

复制代码
#include "main.h"

// 学生功能函数
// 学生登录
void Student_Func(list_str *list)
{
    // 登录
    int user_index = 0;
    clean_screen();
    if (!Student_log_in(list, &user_index))
    {
        printf("登录失败\n");
        exit(-1);
    }

    printf("恭喜你 登录成功\n");

    int op = 0; // 菜单选型

    while (1)
    {
        // 写一个菜单
        printf("1、查成绩\n");
        printf("2、乘法表\n");
        printf("3、猜数字\n");
        printf("4、计算器\n");

        scanf("%d", &op);

        switch (op)
        {
        case 1:
            /* 1、查成绩 */
            list_Student_find(list, list->data[user_index]);
            break;
        case 2:
            /* 2、乘法表 */
            nine_nine();
            break;
        case 3:
            /* 3、猜数字 */
            guess_num();
            break;
        case 4:
            /* 4、计算器 */
            counter();
            break;
        default:
            break;
        }
    }

    // 销毁顺序表
}

// 老师登录
void Teacher_Func(list_str *list)
{
    // 登录

    if (!Teacher_log_in(list))
    {
        printf("登录失败\n");
        exit(-1);
    }

    clean_screen();
    printf("恭喜你 登录成功\n");

    int op = 0; // 菜单选型

    while (1)
    {
        // 写一个菜单
        printf("1、增加学生\n");
        printf("2、删除学生\n");
        printf("3、成绩排序\n");
        printf("4、修改学生\n");

        scanf("%d", &op);

        switch (op)
        {
        case 1:
            /* 1、增加学生 */
            // 1. 写一个函数 从 终端获取学生信息
            // 2. 插入
            list_add_in(list);
            break;
        case 2:
            /* 2、删除学生 */
            list_del(list);
            break;
        case 3:
            /* 3、成绩排序 */
            list_sort(list);
            break;
        case 4:
            /* 4、修改学生 */
            list_Teacher_alter(list);
            break;
        default:
            break;
        }
    }

    // 销毁顺序表
    list_free(&list);
}

int main(int argc, char const *argv[])
{
    // 1 数据初始化 从文件中读取数据到表

    // 1.1 创建表
    list_str *list;

    list_init(&list);

    // 1.2 从文件中读取数据到表
    file_updata_list(list);

    // 2 选择 老师 或 学生登录
    int op = 0;
    clean_screen();
    printf("1、学生登录 2、老师登录\n");
    scanf("%d", &op);

    switch (op)
    {
    case 1: // 学生登录
        Student_Func(list);
        break;
    case 2: // 老师登录
        Teacher_Func(list);
        break;
    default:
        break;
    }

    return 0;
}

五、Makefile

复制代码
Src = ./Src/main.c ./Src/file.c ./Src/list.c

# 编译选项
CFLAGS = -g -I./Inc

Pro:$(Src)
	gcc $(CFLAGS) $(Src) -o Pro

总体来说还是比较简单的,只是要注意多文件的结构和关系。

相关推荐
xiecoding.cn6 分钟前
C语言和C++到底有什么关系?
c语言·开发语言·c++·c/c++·c语言入门
Run_Teenage8 分钟前
C语言每日一练——day_11
c语言·开发语言
白水先森10 分钟前
ArcGIS Pro 制作风台路径图:从数据到可视化
经验分享·arcgispro
iisugar11 分钟前
AI第一天 自我理解笔记--微调大模型
人工智能·笔记
带鱼吃猫24 分钟前
C语言文件操作入门
c语言·开发语言
不不不丶33 分钟前
STM32——WWDG(窗口看门狗)
笔记·stm32·单片机·嵌入式硬件
无名之逆42 分钟前
Hyperlane:Rust 语言打造的 Web 后端框架新标杆
开发语言·前端·网络·网络协议·rust·github·ssl
lsx20240644 分钟前
Ruby 字符串(String)
开发语言
崔婉凝1 小时前
Ruby语言的工业物联网
开发语言·后端·golang
sealaugh321 小时前
aws(学习笔记第三十三课) 深入使用cdk 练习aws athena
笔记·学习·aws