基本信息
源码名称:c语言-学生管理系统源码(适合新手)
源码大小:0.05M
文件格式:.zip
开发语言:C/C++
更新时间:2019-11-13
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300

本次赞助数额为: 3 元 
   源码介绍

学习c语言使用链表,文件存储等功能进行项目开发。学生




/**
 * @author      Shen
 * @description 学生管理系统
 * @copyright   南京晓庄学院
 * @time        2019-11-11  17:48
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* 学生结点 */
typedef struct _STU {
    char arrStuNum[10];     // 学号
    char arrStuName[10];    // 姓名
    float fStuScore;         // 成绩
    struct _STU *pNext;       // 指针域
} STUNODE;
// 声明链表的头和尾
STUNODE *g_pHead = NULL;
STUNODE *g_pEnd = NULL;


/* 函数声明 */
void menu();

// 添加一个学生
void AddStuMSG(char *cNum, char *cName, float fScore);

// 清空链表
void FreeLinkData();

// 链表打印
void ShowStuData();

// 查找信息
void SearchStuData(char *);

// 修改指定学生分数
void UpdateStuByName(char *cStuName, float fNewScore);

// 删除指定学生信息
void DeleteStuByName(char *cStuName);

// 保存到文件
void SaveInfoToFile(char *filePath, char *fileMode);

// 从文件读取信息
void ReadInfoFromFile(char *filePath, char *fileMode);

int main() {
    int iOrder = -1;
    int nFlag = 1;                     // 循环标记
    char arrStuNum[10] = {'\0'};      // 学号
    char arrStuName[10] = {'\0'};     // 姓名
    float fStuScore = -1;              // 成绩
    menu();
    while (nFlag) {
        printf("请选择系统指令(查看指令:8):");
        // 输入系统指令
        scanf("%d", &iOrder);

        switch (iOrder) {
            case 0:
                printf("正在退出系统\n");
                getchar();
                nFlag = 0;
                break;
            case 1:
                // 添加学生信息
                printf("请输入学号: ");
                scanf("%s", arrStuNum);
                fflush(stdin);
                printf("请输入姓名: ");
                scanf("%s", arrStuName);
                fflush(stdin);
                printf("请输入分数:");
                scanf("%f", &fStuScore);
                AddStuMSG(arrStuNum, arrStuName, fStuScore);
                getchar();
                getchar();
                break;
            case 2:
                printf("请输入学生姓名: ");
                // 查找指定学生信息(姓名/学好)
                scanf("%s", arrStuName);
                SearchStuData(arrStuName);
                getchar();
                getchar();
                break;
            case 3:
                // 修改指定学生信息
                printf("请输入学生姓名: ");
                scanf("%s", arrStuName);
                printf("请输入学生成绩:");
                scanf("%f", &fStuScore);
                UpdateStuByName(arrStuName, fStuScore);
                getchar();
                getchar();
                break;
            case 4:
                // TODO: 保存学生信息到文件
                SaveInfoToFile("./stu.txt", "wb ");
                getchar();
                getchar();
                break;
            case 5:
                // 读取学生文件信息
                ReadInfoFromFile("./stu.dat", "rb ");
                getchar();
                getchar();
                break;
            case 6:
                // 删除指定学生信息
                printf("请输入学生姓名: ");
                scanf("%s", arrStuName);
                DeleteStuByName(arrStuName);
                getchar();
                getchar();
                break;
            case 7:
                // 显示所有学生信息
                ShowStuData();
                getchar();
                getchar();
                break;
            case 8:
                menu();
                break;
            default:
                printf("输入指令不正确!\n");
                getchar();
                getchar();
                break;
        }
    }
    SaveInfoToFile("./stu.dat", "wb ");
    // 释放链表
    FreeLinkData();
    system("clear");
    return 0;
}

/**
 * @brief   打印菜单
 */
void menu() {
    printf("************************学生管理系统********************************\n");
    printf("************************本系统操作指令如下***************************\n");
    printf("***                  1、增加一个学生信息                          ***\n");
    printf("***                  2、查找指定学生信息(姓名/学好)                ***\n");
    printf("***                  3、修改指定学生信息                          ***\n");
    printf("***                  4、保存学生信息到文件                        ***\n");
    printf("***                  5、读取学生文件信息                          ***\n");
    printf("***                  6、删除指定学生信息                          ***\n");
    printf("***                  7、恢复删除学生信息                          ***\n");
    printf("***                  8、菜单提示                                 ***\n");
    printf("***                  0、退出系统                                 ***\n");
    printf("*******************************************************************\n");
}

/**
 * @brief 添加学生信息
 */
void AddStuMSG(char *num, char *name, float score) {
    // 检验参数的合法性
    if (NULL == num || NULL == name || score < 0)
    {
        return;
    }
    // 逻辑处理
    // 创建一个结点
    STUNODE *pTemp = (STUNODE *) malloc(sizeof(STUNODE));

    strcpy(pTemp->arrStuNum, num);
    strcpy(pTemp->arrStuName, name);
    pTemp->fStuScore = score;
    pTemp->pNext = NULL;
    // 接链表 两种情况 头尾空
    if (NULL == g_pHead) {
        g_pHead = pTemp;
        g_pEnd = pTemp;             // 指针移动
    }
    else
    {
        g_pEnd->pNext = pTemp;  // 链接
        g_pEnd = pTemp;             // 指针移动
    }
}

/**
 * @brief 清空链表
 */
void FreeLinkData() {
    STUNODE *pTemp = g_pHead;
    while (g_pHead != NULL) {
        pTemp = g_pHead;
        // 链表移动
        g_pHead = g_pHead->pNext;
        // 释放结点
        free(pTemp);
    }
    printf("空间释放成功^_^...\n");
}

/**
 * @brief 链表打印
 */
void ShowStuData() {
    STUNODE *pMov = g_pHead;
    printf("*** 学号 ***        *** 姓名 ***        *** 分数 ***\n");
    while (pMov != NULL) {
        printf(" %s              %s              %.2f    \n", pMov->arrStuNum, pMov->arrStuName, pMov->fStuScore);
        pMov = pMov->pNext;
    }
    printf("打印结束^_^...\n");
}

/**
 * @brief 查找信息
 */
void SearchStuData(char *string) {
    if (NULL == string) {
        printf("参数不符合!\n");
        return;
    }
    STUNODE *pMov = g_pHead;
    while (pMov != NULL) {
        if (strcmp(pMov->arrStuName, string) == 0 || strcmp(pMov->arrStuNum, string) == 0) {
            printf("*** 学号 ***        *** 姓名 ***        *** 分数 ***\n");
            printf(" %s              %s              %.2f    \n", pMov->arrStuNum, pMov->arrStuName, pMov->fStuScore);
        }
        pMov = pMov->pNext;
    }
    printf("搜索成功^_^...\n");
}

/**
 * @brief 根据学生更新成绩
 */
void UpdateStuByName(char *cStuName, float fNewScore) {
    if (NULL == cStuName || fNewScore < 0) {
        printf("输入参数不正确\n");
        return;
    }
    // 定义辅助指针变量
    STUNODE *pMov = g_pHead;

    while (pMov != NULL) {
        if (strcmp(pMov->arrStuName, cStuName) != 0) {
            pMov = pMov->pNext;
        }
        break;
    }
    // 判断当前pMov 是否为空
    if (NULL == pMov) {
        printf("未找到学生信息,无法更改成绩\n");
        return;
    }
    pMov->fStuScore = fNewScore;
    printf("更新成功^_^...\n");
}

/**
 * @brief 删除指定学生结点
 */
void DeleteStuByName(char *cStuName) {
    if (NULL == cStuName) {
        printf("输入参数不正确\n");
        return;
    }
    // 定义辅助指针变量
    STUNODE *pMov = g_pHead;
    STUNODE *pCurrent = pMov;
    while (pMov != NULL) {
        if (strcmp(pMov->arrStuName, cStuName) != 0) {
            pCurrent = pMov;
            pMov = pMov->pNext;
        }
        break;
    }
    // 判断当前pMov 是否为空
    if (NULL == pMov) {
        printf("未找到学生信息,无法删除学生信息\n");
        return;
    }
    pCurrent->pNext = pMov->pNext;
    free(pMov);
    pMov = NULL;
    // 进行删除
    // 1.只有一个结点
//    if (g_pHead == g_pEnd)
//    {
//        free(g_pHead);
//        g_pHead = NULL;
//        g_pEnd = NULL;
//    }
//    else if (g_pHead->pNext == g_pEnd)
//    {
//        if (pMov == g_pHead)
//        {
//            free(g_pHead);
//            g_pHead = g_pEnd;
//            g_pEnd->pNext = NULL;
//        }
//        else
//        {
//            free(g_pEnd);
//            g_pEnd = g_pHead;
//            g_pEnd->pNext = NULL;
//        }
//    }  // 两个结点
//    else
//    {
//        // 删除
//    }
    printf("数据删除成功^_^...\n");
}

/**
 * @brief 保存信息到文件
 * @param filePath
 * @param fileMode
 */
void SaveInfoToFile(char *filePath, char *fileMode) {
    if (NULL == filePath || NULL == fileMode) {
        printf("保存参数存在问题\n");
        return;
    }
    if (g_pHead == NULL) {
        printf("暂无数据,无需保存\n");
        return;
    }
    STUNODE *pMov = g_pHead;
    FILE *fp = fopen(filePath, fileMode);

    if (NULL == fp) {
        fp = fopen(filePath, "wb ");
    }
    fprintf(fp, "学号\t\t姓名\t\t分数\r\n");
    while (pMov != NULL) {
        fprintf(fp, "%s\t\t%s\t\t%f", pMov->arrStuNum, pMov->arrStuName, pMov->fStuScore);
        fprintf(fp,"\r\n");
        pMov = pMov->pNext;
    }
    fclose(fp);
}

/**
 * @brief   从文件读取信息
 * @param filePath
 * @param fileMode
 */
void ReadInfoFromFile(char *filePath, char *fileMode) {
    if (NULL == filePath || NULL == fileMode) {
        printf("保存参数存在问题\n");
        return;
    }

    FILE *fp = fopen(filePath, fileMode);
    char num[10] = {'\0'};
    char name[10] = {'\0'};
    char score1[10] = {'\0'};
    float score = -1;
    int flag;

    if (NULL == fp)
    {
        printf("文件打开失败\n");
        return;
    }
    flag = fscanf(fp, "%s%s%s", num, name, score1);
    while (flag > 0)
    {
        // 清空
        memset(num, 0, 10);
        memset(name, 0, 10);
        memset(score1, 0, 10);
        score = -1;
        // 数据读取
        flag = fscanf(fp, "%s%s%f", num, name, &score);
        AddStuMSG(num, name, score);
    }
    fclose(fp);
}