用链表编写学生管理系统(涵盖文件的输入输出)

学过链表的大家都知道,它是一种动态的数据结构,但是它理解起来是比较困难的,但是用链表存储数据是非常好用的,可以使我们的程序更加具有健壮性。为了初学者理解单项链表更加快,今天就用链表和文件操作写了一控制台的学生管理系统,希望可以帮助大家更好的理解链表。

程序实现的功能:

源代码如下

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void AppendNode(long long studentID, char studentName[10], char studentSex[4], int score[4]);//添加数据
void DisplayNode(struct link *head);//显示数据
void InsertNode(long long studentID, char studentName[10], char studentSex[4], int score[4]);//插入一条数据;按总分的从大到小排序
void InsertNodeNumber(long long studentID, char studentName[10], char studentSex[4], int score[4]);//按学号的从小到大排序
void NumberSorting(int flag);//按从大到小对数据进行排序;1、对总分进行排序,2、对学号进行排序
void DeleteNodeID();//输入学号删除
void DeleteNodeName();//输入学号删除
void DeleteMemory(struct link *head);//删除聊表所占用的内存;
void Save();//保存数据
void Open();//打开数据
void FindID();//按学号查找学生
void FindName();//按姓名查找学生;
void Menu();
typedef struct student
{
    long long studentID;
    char studentName[10];
    char studentSex[4];
    int score[4];
}STU;
struct link
{
    STU student;
    struct link *next;
};
struct link *head = NULL;//保存输入的学生信息数据
struct link *head1 = NULL;//保存排序后的学生信息数据
int main()
{
    long long studentID;
    char studentName[10];
    char studentSex[4];
    int score[4];//定义要输入学生信息的变量;
    char c;
    int menu;//保存要进行的选项;
    Open();
    while (1)
    {
        system("pause");
        Menu();
        printf("请输入要进行的操作:");
        scanf("%d", &menu);
        switch (menu)
        {
        case 0:exit(0);
            break;
        case 1:
            printf("请输入Y或y来添加数据\n");
            scanf(" %c", &c);
            while (c == 'y' || c == 'Y')
            {
                printf("请输入学生学号:");
                scanf("%lld", &studentID);
                printf("请输入学生姓名:");
                scanf("%s", &studentName);
                printf("请输入学生性别:");
                scanf("%s", &studentSex);
                int i = 0;
                printf("请分别输入学生四门课的成绩:");
                for (i = 0; i < 4; i++)
                {
                    scanf("%d", &score[i]);
                }
                AppendNode(studentID, studentName, studentSex, score);
                printf("请输入Y或y来添加数据\n");
                scanf(" %c", &c);
            }
            DisplayNode(head);
            break;
        case 2:
             FindID();
            break;
        case 3:
             FindName();
            break;
        case 4:
             DeleteNodeID();
            break;
        case 5:
             DeleteNodeName();
        case 6:
            NumberSorting(1);
            DeleteMemory(head1);
            head1 = NULL;
            break;
        case 7:
            NumberSorting(2);
            DeleteMemory(head1);
            head1 = NULL;
            break;
        default:
            printf("输入有误!请重新输入");
        }
    }
    Save();
    DeleteMemory(head);
    DeleteMemory(head1);
    system("pause");
}
void AppendNode(long long studentID, char studentName[10], char studentSex[4], int score[4])
{
    struct link *p = NULL, *pr = head;
    p = (struct link *) malloc(sizeof(struct link));
    if (p == NULL)
    {
        printf("申请内存失败");
        return;
    }
    if (head == NULL)
    {
        head = p;
    }
    else {
        while (pr->next != NULL)
        {
            pr = pr->next;
        }
        pr->next = p;
    }
    p->student.studentID = studentID;
    strcpy(p->student.studentName, studentName);
    strcpy(p->student.studentSex, studentSex);
    p->student.score[0] = score[0];
    p->student.score[1] = score[1];
    p->student.score[2] = score[2];
    p->student.score[3] = score[3];
    p->next = NULL;
    return;
}
void NumberSorting(int flag)
{
    struct link *p = head;
    struct link *p1 = head1;
    int sum = 0;
        if(p == NULL)
        {
            printf("没有数据,无法排序");
            return;
        }
        while (p!=NULL)
        {
            switch (flag)
            {
            case 1:
                InsertNode(p->student.studentID, p->student.studentName, p->student.studentSex, p->student.score);
                break;
            case 2 :
                InsertNodeNumber(p->student.studentID, p->student.studentName, p->student.studentSex, p->student.score);
                break;
            default:
                printf("程序异常,请重试!");
                break;
            }
            p = p->next;    
        }
        DisplayNode(head1);
}
void DisplayNode(struct link *head)
{
    struct link *p = head;
    if (p == NULL)
    {
        return;
    }
    printf("%lld", p->student.studentID);
    printf("%10s", p->student.studentName);
    printf("%5s", p->student.studentSex);
    {
        int i = 0;
        for (i = 0; i < 4; i++)
        {
            printf("%4d", p->student.score[i]);
        }
    }
    printf("\n");
    DisplayNode(p->next);
}
void DeleteMemory(struct link *head)
{
    struct link *p = head, *pr = NULL;
    while (p != NULL)
    {
        pr = p;
        p = p->next;
        free(pr);
    }
    
}
void InsertNodeNumber(long long studentID, char studentName[10], char studentSex[4], int score[4])
{
    struct link *pr = head1, *p = head1, *temp = NULL;
    p = (struct link *)malloc(sizeof(struct link));
    if (p == NULL)
    {
        printf("内存申请失败");
        return;
    }
    p->next = NULL;
    p->student.studentID = studentID;
    strcpy(p->student.studentName, studentName);
    strcpy(p->student.studentSex, studentSex);
    p->student.score[0] = score[0];
    p->student.score[1] = score[1];
    p->student.score[2] = score[2];
    p->student.score[3] = score[3];
    if (head1 == NULL)
    {
        head1 = p;
    }
    else
    {
        while (pr->student.studentID < studentID&&pr->next != NULL)
        {
            temp = pr;
            pr = pr->next;    
        }
        if (pr->student.studentID >= studentID)
        {
            if (pr == head1)
            {
                p->next = head1;
                head1 = p;
            }
            else
            {
                pr = temp;
                p->next = pr->next;
                pr->next = p;
            }
        }
        else
        {
            pr->next = p;
        }
    }
    return;
}

void InsertNode(long long studentID, char studentName[10], char studentSex[4], int score[4])
{
    struct link *pr = head1, *p = head1, *temp = NULL;
    int sum, sum1;
    p = (struct link *)malloc(sizeof(struct link));
    if (p == NULL)
    {
        printf("内存申请失败");
        return;
    }
    p->next = NULL;
    p->student.studentID = studentID;
    strcpy(p->student.studentName, studentName);
    strcpy(p->student.studentSex, studentSex);
    p->student.score[0] = score[0];
    p->student.score[1] = score[1];
    p->student.score[2] = score[2];
    p->student.score[3] = score[3];
    sum = p->student.score[0] + p->student.score[1] + p->student.score[2] + p->student.score[3];
    if (head1 == NULL)
    {
        head1 = p;
    }
    else
    {
        sum1 = pr->student.score[0] + pr->student.score[1] + pr->student.score[2] + pr->student.score[3];
        while (sum1 > sum&&pr->next != NULL)
        {
            temp = pr;
            pr = pr->next;
            sum1 = pr->student.score[0] + pr->student.score[1] + pr->student.score[2] + pr->student.score[3];
        }
        if (sum1 <= sum)
        {
            if (pr == head1)
            {
                p->next = head1;
                head1 = p;
            }
            else
            {
                pr = temp;
                p->next = pr->next;
                pr->next = p;
            }
        }
        else
        {
            pr->next = p;
        }
    }
    return;
}

void DeleteNodeID()//输入学号删除
{
    struct link *p = head, *pr = head;
    long long studentID = 0;
    if (head == NULL) {
        printf("对不起,没有数据可以删除");
        return;
    }
    printf("请输入你要删除的学生的学号");
    scanf("%s", studentID);
    while (studentID != p->student.studentID&&p->next != NULL)
    {
        pr = p;
        p = p->next;
    }
    if (studentID == p->student.studentID)
    {
        if (p == head) {
            head = p->next;
        }
        else
        {
            pr->next = p->next;
        }
        free(p);
    }
    else
    {
        printf("你要查找的这个数据未找到");
    }
    return;
}
void DeleteNodeName()//输入姓名删除
{
    struct link *p = head, *pr = head;
    char studentName[10] = "";
    if (head == NULL) {
        printf("对不起,没有数据可以删除");
        return;
    }
    printf("请输入你要删除的学生的姓名:");
    scanf("%s", studentName);
    while (0!=strcmp(studentName,p->student.studentName)&&p->next != NULL)
    {
        pr = p;
        p = p->next;
    }
    if (0==strcmp(studentName, p->student.studentName))
    {
        if (p == head) {
            head = p->next;
        }
        else
        {
            pr->next = p->next;
        }
        free(p);
    }
    else
    {
        printf("你要查找的这个数据未找到");
    }
    return;
}
void Save()//保存链表中的数据
{
    FILE *fp;
    struct link *p = head;
    if ((fp = fopen("demo.txt", "w")) == NULL)
    {
        printf("打开文件失败");
        return;
    }
    while (p != NULL)
    {
        fprintf(fp, "%20lld%10s%5s%4d%4d%4d%4d", p->student.studentID, p->student.studentName, p->student.studentSex,
            p->student.score[0], 
            p->student.score[1], 
            p->student.score[2], 
            p->student.score[3]);
        p = p->next;
    }
    fclose(fp);
    return;
}
void Open()//将文件中获得的数据写入到链表中
{
    long long studentID;
    char studentName[10];
    char studentSex[4];
    int score[4];
    FILE *fp;
    char c;
    if ((fp = fopen("demo.txt", "r")) == NULL)
    {
        printf("文件打开失败");
        return;
    }
    while ((c = fgetc(fp))!=EOF)
    {
        fscanf(fp, "%20lld", &studentID);
        fscanf(fp, "%10s", studentName);
        fscanf(fp, "%5s", studentSex);
        fscanf(fp, "%4d", &score[0]);
        fscanf(fp, "%4d", &score[1]);
        fscanf(fp, "%4d", &score[2]);
        fscanf(fp, "%4d", &score[3]);
        AppendNode(studentID, studentName, studentSex, score);
    }
    fclose(fp);
}
void FindID()
{
    struct link *p = head;
    long long studentID=0;
    if (head == NULL)
    {
        printf("没有数据查找");
        return;
    }
    printf("请输入你要查找的学生的学号:");
    scanf("%lld", &studentID);
    while (studentID != p->student.studentID&&p->next != NULL)
    {
        p = p->next;
    }
    if (studentID == studentID)
    {
        printf("%lld", p->student.studentID);
        printf("%10s", p->student.studentName);
        printf("%5s", p->student.studentSex);
        {
            int i = 0;
            for (i = 0; i < 4; i++)
            {
                printf("%4d", p->student.score[i]);
            }
        }
    }
    else{
        printf("没有你要查找的数据");
    }
    return;
}
void FindName()
{
    struct link *p = head;
    char studentName[10] = "";
    if (head == NULL)
    {
        printf("没有数据查找");
        return;
    }
    printf("请输入你要查找的学生的姓名:");
    scanf("%s", studentName);
    while (0!=strcmp(studentName,p->student.studentName)&&p->next != NULL)
    {
        p = p->next;
    }
    if (0==strcmp(studentName,p->student.studentName))
    {
        printf("%lld", p->student.studentID);
        printf("%10s", p->student.studentName);
        printf("%5s", p->student.studentSex);
        {
            int i = 0;
            for (i = 0; i < 4; i++)
            {
                printf("%4d", p->student.score[i]);
            }
        }
    }
    else{
        printf("没有你要查找的数据");
    }
    return;
}
void Menu()
{
    system("cls");//清平操作; 
    printf("\n\n\n\n\n");//输入回车,形成格式; 
    printf("\t\t|...........学生管理系统..............|\n");//
    printf("\t\t|\t 0.退出。                     |\n");//“/t”水平制表,相当于一个tab键; 
    printf("\t\t|\t 1.添加学生成绩信息!         |\n");
    printf("\t\t|\t 2.查找学生(按学号)信息!     |\n");
    printf("\t\t|\t 3.查找学生(按姓名)信息!     |\n");
    printf("\t\t|\t 4.删除学生成绩(按学号)信息! |\n");
    printf("\t\t|\t 5.删除学生成绩(按姓名)信息! |\n");
    printf("\t\t|\t 6.按总分排序!               |\n");
    printf("\t\t|\t 7.按学号排序!               |\n");
    printf("\t\t|...........学生管理系统..............|\n");//
}

如对程序有什么好的建议欢迎评论指教。。。。。。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏YG小书屋

ES中文分词器之精确短语匹配(解决了match_phrase匹配不全的问题)

50740
来自专栏杨建荣的学习笔记

一个SQL语句引发的ORA-00600错误排查(一) (r9笔记第64天)

最近有一个同事问我一个问题,说他运行一个SQL语句抛出了ORA-00600的错误,想让我帮忙分析一下,这种问题听了确实有兴趣,了解了问题的大体情 况之后,发现这...

36440
来自专栏lgp20151222

postgresql安装,java简单使用postgresql

由于本人的学过的技术太多太乱了,于是决定一个一个的整合到一个springboot项目里面。

9210
来自专栏Alan's Lab

[Coursera][From Nand to Tetris / Part I] 第六周 汇编器项目 python 实现

今天折腾一上午,终于 完成了 Coursera 上 From Nand to Tetris / Part I 这个课程的最后一个汇编器项目。这套课程真是没白跟,...

16130
来自专栏编程札记

Lucene构建个人搜索引擎解析

简单来说,Lucene提供了一套完整的工具来帮助开发者构建自己的搜索引擎,开发者只需要import Lucene对应的package即可快速地开发构建自己的业务...

23720
来自专栏性能与架构

Mysql Join语句的优化

1. 尽可能减少Join语句中Nested Loop的循环总次数 最有效的办法是让驱动表的结果集尽可能地小,这也正是在本章第二节中所提到的优化基本原则之一——“...

39560
来自专栏AhDung

【SQL】分享表值函数FMakeRows,用于生成行

评论中又有一位【笑东风】兄给出改善建议,在此先感谢他。原理是借助行数较多的一个系统视图sys.all_columns与自身做cross join,以得到大量现成...

9730
来自专栏腾讯云流计算

Apache Calcite 功能简析及在 Flink 的应用

• Apache Calcite 是一个动态数据的管理框架,可以用来构建数据库系统的语法解析模块

1.7K70
来自专栏GIS讲堂

SQL之学生选课数据库

Restrict说明删除是有条件的,cascade说明该表的删除没有任何限制。

53730
来自专栏企鹅号快讯

利用pandas进行数据分析(二):索引与层次化索引

继上一节的基本数据结构的介绍之后,本节继续介绍中操作和的基本手段。一个最常用的操作就是索引,如何根据分析目的对和进行索引访问得到数据是利用进行数据分析的基本技能...

23790

扫码关注云+社区

领取腾讯云代金券