C语言链表项目-学生信息管理系统

核心知识

单向链表基本操作+对文件的基本操作

使用说明

  • 请先建好一个.txt文件并记下路径名,文件可以为空,也可以预先存好数据
  • 建议创建一个空文件,通过程序来向文件中存数据。
  • 手动去文件中存数据需要严格按照格式。

如果想预先手动存一些数据,需要按照以下格式:

在某些编译器上,姓名可能不支持中文


姓名1 语文 数学 英语 计算机 C语言 平均分 总分1

姓名n 语文 数学 英语 计算机 C语言 平均分 总分n


文件结尾,也就是最后一行的总分n后面不要有任何字符

代码附上

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

#define MAXNAME 30
#define MAXSUBJECT 5
#define SPACE ' '

typedef struct student
{
    char name[MAXNAME];
    int score[MAXSUBJECT];
    double aver;
    int sum;

} STUDENT;

typedef struct node
{
    STUDENT data;
    struct node *next;

} NODE, *LIST;

int i, choice;
char ch, c, c2;
char s1[10] = "name";
char s2[10] = "average";
char s3[10] = "sum";
char s4[10] = "chinese";
char s5[10] = "math";
char s6[10] = "english";
char s7[10] = "computer";
char s8[10] = "c";
char FileName[100];
LIST headp = NULL;

// 读入文件时,添加链表成员
void AddFscanf(NODE);

// 使用说明
void Instructions();

// 进行完一次操作后,询问是否继续
void Ask();

// 打印分割线
void SplitLine();

// 操作1,用户输入时,添加链表成员,
void AddUserInput();

// 操作2,删除节点
void Delete();

// 操作3,查询某个节点信息
void Inquire();

// 操作4,更新某个节点信息
void Update();

// 操作5,排序学生信息
void Sort();

// 操作6,保存信息到文件中
void Save();

// 操作7,打印链表
void Print();

// 释放链表
void Free();

int main(void)
{

    FILE *fp = NULL;
    NODE head;
    NODE temp;
    headp = &head;
    head.next = NULL;
    temp.next = NULL;
    printf("请输入文件的绝对路径+文件名(仅限 .txt 文件)\n\n");
    printf("例如,若您要打开D盘根目录下的 info.txt 文件\n");
    printf("则应输入\"D:/info.txt\"(您输入的字符均应为英文字符)\n");
    scanf("%s", FileName);
    getchar();
    if ((fp = fopen(FileName, "r")) == NULL)
    {
        printf("\n\"%s\" 打开失败\n\n", FileName);
        exit(EXIT_FAILURE);
    }
    printf("\n\"%s\" 打开成功!\n", FileName);
    printf("\n正在鉴定文件是否为空...\n");
    c2 = getc(fp);
    fclose(fp);
    if (c2 == EOF)
        printf("打开的文件为空文件,仅可进行写入操作!\n");
    else
    {
        printf("文件非空,可进行任意操作\n\n");
        printf("正在重新打开该文件...\n");
        if ((fp = fopen(FileName, "r")) == NULL)
        {
            printf("can't open \"%s\" \n", FileName);
            exit(EXIT_FAILURE);
        }
        printf("正在读取该文件中的数据...\n");
        while (1)
        {
            fscanf(fp, "%s", temp.data.name);
            for (i = 0; i < MAXSUBJECT; i++)
                fscanf(fp, "%d", &temp.data.score[i]);
            fscanf(fp, "%lf", &temp.data.aver);
            fscanf(fp, "%d", &temp.data.sum);
            ch = getc(fp);
            AddFscanf(temp);
            if (ch == EOF)
                break;
        }
        printf("文件数据读取成功!\n");
        fclose(fp);
    }
    while (1)
    {
        Instructions();
        switch (choice)
        {
        case 1:
            AddUserInput();
            break;
        case 2:
            Delete();
            break;
        case 3:
            Inquire();
            break;
        case 4:
            Update();
            break;
        case 5:
            Sort();
            break;
        case 6:
            Save();
            break;
        case 7:
            Print();
            break;
        case 0:
            printf("Bye~  Have a good day! \n\n");
            exit(EXIT_FAILURE);
        default:
            break;
        }
        Ask();
    }

    Free();
    return 0;
}

void Free()
{
    LIST temp = headp->next;
    LIST deletep = NULL;
    while (temp != NULL)
    {
        deletep = temp;
        temp = temp->next;
        free(deletep);
    }
}
void Save()
{
    FILE *fp = NULL;
    int flag = 0;
    LIST temp = headp->next;
    if ((fp = fopen(FileName, "w")) == NULL)
    {
        printf("can't open \" %s \" \n", FileName);
        exit(EXIT_FAILURE);
    }
    while (temp != NULL)
    {
        if (flag)
            fprintf(fp, "\n");
        fprintf(fp, "%s   ", temp->data.name);
        for (i = 0; i < MAXSUBJECT; i++)
            fprintf(fp, "%d   ", temp->data.score[0]);
        fprintf(fp, "%.2f   ", temp->data.aver);
        fprintf(fp, "%d", temp->data.sum);
        flag = 1;
        temp = temp->next;
    }
    printf("\n保存成功!");
    fclose(fp);
}
void Sort()
{
    LIST temp = NULL;
    STUDENT t;
    int lenth = 0, j;
    if (headp->next == NULL)
    {
        printf("数据为空!仅可进行写入操作!\n");
        return;
    }
    temp = headp->next;
    while (temp != NULL)
    {
        lenth++;
        temp = temp->next;
    }
    for (i = lenth - 1; i > 0; i--)
    {
        temp = headp->next;
        for (j = 0; j < i; j++)
        {
            if (temp->data.sum < temp->next->data.sum)
            {
                t = temp->data;
                temp->data = temp->next->data;
                temp->next->data = t;
            }
            else if (temp->data.sum == temp->next->data.sum)
            {
                if (strcmp(temp->data.name, temp->next->data.name) > 0)
                {
                    t = temp->data;
                    temp->data = temp->next->data;
                    temp->next->data = t;
                }
            }
            temp = temp->next;
        }
    }
    printf("\n排序成功!");
}

void Update()
{
    LIST temp = NULL;
    int flag;
    char NAME[MAXNAME];
    if (headp->next == NULL)
    {
        printf("数据为空!\n");
        return;
    }
    temp = headp;
    printf("请输入要更新的学生姓名:\n");
    while (1)
    {
        temp = headp;
        fflush(stdin);
        scanf("%s", NAME);
        getchar();
        while (temp != NULL)
        {
            if (strcmp(temp->data.name, NAME) == 0)
                break;
            temp = temp->next;
        }
        if (temp == NULL)
        {
            printf("错误!库中没有该学生的信息\n");
            printf("键入'n'退出该功能,或键入'y'重新输入\n");
            while (1)
            {
                flag = 0;
                scanf("%c", &c);
                getchar();
                if (c == 'y' || c == 'Y')
                {
                    printf("请重新输入要更新学生的姓名\n");
                    break;
                }
                else if (c == 'n' || c == 'N')
                {
                    flag = 1;
                    break;
                }
                else
                    printf("输入非法!请输入'y'或'n',不要输入其它字符\n");
            }
            if (flag)
                break;
        }
        else
        {
            temp->data.sum = 0;
            temp->data.aver = 0.0;
            printf("请依次输入该学生语文、数学、英语、计算机、C语言,五门课的成绩\n");
            for (i = 0; i < MAXSUBJECT; i++)
            {
                scanf("%d", &temp->data.score[i]);
                temp->data.sum += temp->data.score[i];
            }
            temp->data.aver = temp->data.sum * 1.0 / MAXSUBJECT;
            printf("\n更新成功!");
            break;
        }
    }
}
void Inquire()
{
    LIST temp = NULL;
    int flag;
    char NAME[MAXNAME];
    if (headp->next == NULL)
    {
        printf("数据为空!\n");
        return;
    }
    temp = headp;
    printf("请输入要查询的学生姓名:\n");
    while (1)
    {
        temp = headp;
        fflush(stdin);
        scanf("%s", NAME);
        getchar();
        while (temp != NULL)
        {
            if (strcmp(temp->data.name, NAME) == 0)
                break;
            temp = temp->next;
        }
        if (temp == NULL)
        {
            printf("错误!库中没有该学生的信息\n");
            printf("键入'y'重新输入或'n'退出该功能\n");
            while (1)
            {
                flag = 0;
                scanf("%c", &c);
                getchar();
                if (c == 'y' || c == 'Y')
                {
                    printf("请重新输入要查询学生的姓名\n");
                    break;
                }
                else if (c == 'n' || c == 'N')
                {
                    flag = 1;
                    break;
                }
                else
                    printf("输入非法!请输入'y'或'n',不要输入其它字符\n");
            }
            if (flag)
                break;
        }
        else
        {
            printf("\n\n%s的信息如下:\n\n", NAME);
            printf("%-10s %-8s %-10s %-10s %-10s %-10s %6s\n",
                   s2, s3, s4, s5, s6, s7, s8);
            printf("%-10.2f %-10d",
                   temp->data.aver, temp->data.sum);
            for (i = 0; i < MAXSUBJECT; i++)
                printf("%-12d", temp->data.score[i]);
            printf("\n");
            break;
        }
    }
}

void Delete()
{
    LIST temp = NULL, deletp = NULL;
    int flag;
    char NAME[MAXNAME];
    if (headp->next == NULL)
    {
        printf("数据为空!\n");
        return;
    }
    temp = headp;
    printf("请输入要删除的学生的姓名:\n");
    // 现在这个情况,链表一定不为空
    while (1)
    {
        temp = headp;
        fflush(stdin);
        scanf("%s", NAME);
        getchar();
        // 搜索要删除的学生姓名所在结点的上一个
        while (temp->next != NULL)
        {
            if (strcmp(temp->next->data.name, NAME) == 0)
                break;
            temp = temp->next;
        }
        if (temp->next == NULL)
        {
            flag = 0;
            printf("您要删除的学生不存在,键入'y'重新输入或'n'退出该功能\n");
            while (1)
            {
                c = getchar();
                getchar();
                if (c == 'y' || c == 'Y')
                {
                    printf("请重新输入学生姓名:\n");
                    break;
                }
                else if (c == 'n' || c == 'N')
                {
                    flag = 1;
                    break;
                }
                else
                    printf("输入非法!请重新输入'y' or 'n'\n");
            }
            if (flag)
                break;
        }
        else
        {
            // 要删除的结点是最后一个结点
            if (temp->next->next == NULL)
            {
                free(temp->next);
                temp->next = NULL;
            }
            else
            {
                deletp = temp->next;
                temp->next = temp->next->next;
                free(deletp);
            }
            printf("\n删除成功!");
            break;
        }
    }
}
void Ask()
{
    fflush(stdin);
    printf("\n\n输入'n'结束该信息管理系统,或输入其它任意字符回到菜单\n");
    scanf("%c", &c);
    getchar();
    if (c == 'n')
    {
        printf("\nBye~  Have a good day! \n\n");
        exit(EXIT_FAILURE);
    }
}
void AddUserInput()
{
    int flag = 0, flag2 = 0;
    LIST newp = NULL;
    LIST temp = headp->next;
    printf("请输入学生姓名:\n");
    while (1)
    {
        newp = (LIST)malloc(sizeof(NODE));
        flag = 0;
        temp = headp->next;
        fflush(stdin);
        scanf("%s", newp->data.name);
        getchar();
        while (temp != NULL)
        {
            if (strcmp(newp->data.name, temp->data.name) == 0)
            {
                flag = 1;
                break;
            }
            temp = temp->next;
        }
        if (flag)
        {
            printf("\n库中已有该名字,请退回到菜单选择\"更新信息\"或选择重新输入名字\n");
            printf("是否重新输入?(y/n)\n");
            while (1)
            {
                flag2 = 0;
                c = getchar();
                getchar();
                if (c == 'y')
                {
                    printf("\n您选择了'y',请重新输入名字\n");
                    break;
                }
                else if (c == 'n')
                {

                    flag2 = 1;
                    break;
                }
                else
                {
                    printf("\n请输入'y'或'n',不要输入其它字符!\n");
                    printf("请重新输入'y'或'n' \n");
                }
            }
            if (flag2)
                break;
        }
        else
        {
            temp = headp;
            while (temp->next != NULL)
                temp = temp->next;
            temp->next = newp;
            newp->next = NULL;
            newp->data.sum = 0;
            newp->data.aver = 0.0;

            printf("请依次输入该学生语文、数学、英语、计算机、C语言,五门课的成绩\n");
            for (i = 0; i < MAXSUBJECT; i++)
            {
                scanf("%d", &newp->data.score[i]);
                newp->data.sum += newp->data.score[i];
            }
            newp->data.aver = newp->data.sum * 1.0 / MAXSUBJECT;
            printf("\n添加成功!\n");
            printf("是否继续添加?(输入'n'结束该功能,输入其它任意字符继续添加)\n");
            fflush(stdin);
            c = getchar();
            getchar();
            if (c == 'n')
                break;
            else
                printf("\n请继续输入要添加的学生的姓名\n");
        }
    }
}

void AddFscanf(NODE newNode)
{
    LIST newp = (LIST)malloc(sizeof(NODE));
    LIST temp = headp;
    while (temp->next != NULL)
        temp = temp->next;
    temp->next = newp;
    newp->next = NULL;
    newp->data.sum = 0;
    newp->data.aver = 0.0;
    strcpy(newp->data.name, newNode.data.name);
    for (i = 0; i < MAXSUBJECT; i++)
        newp->data.score[i] = newNode.data.score[i];
    newp->data.sum = newNode.data.sum;
    newp->data.aver = newNode.data.aver;
}

void Print()
{
    LIST temp = NULL;
    if (headp->next == NULL)
    {
        printf("数据为空!\n");
        return;
    }
    temp = headp;
    printf("已存储的数据为:\n");
    SplitLine();
    printf("%-15s %-10s %-8s %-10s %-10s %-10s %-10s %6s\n",
           s1, s2, s3, s4, s5, s6, s7, s8);
    while (temp->next != NULL)
    {
        printf("%-15s %-10.2f %-10d",
               temp->next->data.name, temp->next->data.aver,
               temp->next->data.sum);
        for (i = 0; i < MAXSUBJECT; i++)
            printf("%-12d", temp->next->data.score[i]);
        printf("\n");
        temp = temp->next;
    }
    SplitLine();
}

void SplitLine()
{
    printf("\n========================================================================================\n\n");
}

void Instructions()
{
    printf("\n\n\t   The Student's Grade Management System\n\n");
    printf("---------------------Student  Menu------------------------\n");

    if (headp->next == NULL)
    {
        printf("* 1 输入学生信息\t\t\t * 0 退出学生系统\n");
        printf("----------------------------------------------------------\n");
        printf("此时数据为空!仅支持输入学生信息!\n");
        printf("Enter your choice 0 or 1: ");
    }
    else
    {
        printf("* 1 输入学生信息\t\t\t * 2 删除学生信息\n");
        printf("* 3 查询学生信息\t\t\t * 4 更新学生信息\n");
        printf("* 5 排序学生信息\t\t\t * 6 保存学生信息\n");
        printf("* 7 显示学生信息\t\t\t * 0 退出学生系统\n");
        printf("----------------------------------------------------------\n");
        printf("Enter your choice [0 - 9]: ");
    }
    scanf("%d", &choice);
    printf("\n\n");
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值