一个简单的C/C++编写的信息管理系统(适合初学者练手用)

这是作者大一时候的课程作业,多年后发现还保留着,就放上来分享下。

包含基本的数据结构设计;数据的录入、增删查改、排序、统计和全输出;和最后的退出自动保存数据等基本操作。

这里做的是学生信息管理系统,读者可以自行改成图书管理系统等其他信息管理系统,难度不大。可以直接复制代码到IDE里跑。

话不多说,直接上头文件:

//head.h
#include<stdio.h>
#include<malloc.h>//分配空间头文件
#include<string.h>//字符串头文件
#include<string>//C++字符串头文件
#include<queue>//队列头文件,优先队列会用到
#include<stdlib.h>//一些界面操作函数会用到
#include <unistd.h>//清空文件的函数ftruncate
#define MaxSize 100//这个是控制最大节点量的,可调大
using namespace std;//C++的默认命名空间
//定义信息节点类型
typedef struct SNode
{
    long long student_number;//学号
    char name[20];//姓名
    char gender[10];//性别
    char academy[20];//学院
    char major[20];//专业班级
    int English;//英语成绩
    int computer;//计算机成绩
    int math;//数学成绩
    int total_points;//总分
    int length;//这个是统计节点数目的数据
    bool operator<(const SNode& lhs)const{return lhs.total_points>total_points;}//优先队列运算符重载,不懂可百度,可重载<,>,=
    struct SNode *next;//节点指针
}ADDR;

//以下是菜单功能函数
void welcome();//欢迎界面
void luru(ADDR *&h);//录入
void deletedata(ADDR *&h);//删除
void add_data(ADDR *&h);//增添
void find_data(ADDR *&h);//查找
void sort_data(ADDR *&h);//排序
void statistics(ADDR *&h);//统计
void modification(ADDR *&h);//修改
void save(ADDR *&h);//写入磁盘文件

//以下是数据结构函数
void InitList(ADDR *&L);//给链表分配空间
void DestroyList(ADDR *&L);//删除链表
void DispList(ADDR *L);//输出全链表
bool GetElem(ADDR *L,int i);//输出节点数据
int LocateElem(ADDR *L,long long e);//按学号查找
bool ListInsert(ADDR *&L,int &i);//插入节点
bool ListInsert2(ADDR *&L,int &i,FILE *&fp);//读取文件
bool ListDelete(ADDR *&L,int i);//删除节点
int LocateElem2(ADDR *L,char s[]);//按姓名查找
bool modification_data(ADDR *&h,int i);//修改数据
void read_in(ADDR *L,FILE *&fp);//写入文件

头文件包含了整个系统的结构和目录,看多几遍,下面的就好理解了。

主函数(main.cpp),系统的入口,读者可以从这里开始理清整个系统结构:

//main.cpp
#include "head.h"

void Menu_select(ADDR *&h);//功能选择函数

int main()
{
    int n;
    ADDR *top;//保存数据节点的单链表
    InitList(top);//初始化单链表
    top->length=0;//目前没有节点
    welcome();//用户交互页面
    Menu_select(top);//选择执行的操作
    DestroyList(top);//退出系统前删除数据链表
    printf("\tGoodbye!\n");
    return 0;
}
void Menu_select(ADDR *&h)
{
	int cn=0;//保存操作序号
 	while(scanf("%d",&cn)!=EOF)
	{
        if(cn<1|| cn>9 )//这里只有9个功能
        {
            printf("\n\t输入错误,重选1-9:");
            continue;
        }
        switch(cn)
		{
            case 1://录入数据
            {
                luru(h);
                break;
            }
            case 2://删除数据
            {
                deletedata(h);
                break;
            }
            case 3://添加数据
            {
                add_data(h);
                break;
            }
            case 4://查询数据
            {
                find_data(h);
                break;
            }
            case 5://排序数据
            {
                sort_data(h);
                break;
            }
            case 6://统计数据
            {
                statistics(h);
                break;
            }
            case 7://修改数据
            {
                modification(h);
                break;
            }
            case 8://按录入顺序全输出数据
            {
                printf("\t学生的基本信息如下\n\t(格式为:学号 姓名 性别 学院 专业班级 外语成绩 计算机成绩 数学成绩 三科总分):\n");
                DispList(h);
                printf("\n");
                printf("\n\t按回车跳回主菜单!\n");
                getchar();
                getchar();
                system("cls");
                break;
            }
            case 9://保存并退出
            {
                save(h);
                return ;
            }
		}
		welcome();//交互页面
	}
}

欢迎页面(或者说是交互页面):

//交互页面.cpp。
#include "head.h"

void welcome(){
    /*
    printf("\t\t\t\t\t* 欢迎来到学生信息管理系统 *\n");
    printf("\t**********************************************************************************\n");
    printf("\t*   数据保存在D://学生信息数据.txt中,若文件不存在请先进行创建,请知悉!         *\n");
    printf("\t*                            ▂▃▅▆█谢谢使用!█▆▅▃▂                       *\n");
    printf("\t**********************************************************************************\n");
    printf("\n");
    printf("\n按回车继续。\n");
    getchar();
    system("cls");
    printf("\n");
    */
	printf("\t\t\t* 欢迎来到学生信息管理系统 *\n");
    printf("\t************************************************************\n");
    printf("\t* [1] 录入学生信息                 [2] 删除学生信息        *\n");
    printf("\t* [3] 增加学生信息                 [4] 查找学生信息        *\n");
    printf("\t* [5] 排序学生信息                 [6] 统计学生信息        *\n");
    printf("\t* [7] 修改学生信息                 [8] 输出学生信息        *\n");
    printf("\t* [9] 保存学生信息并退出                                   *\n");
    printf("\t************************************************************\n");
    printf("\t左边数字对应功能选择,请选1-9:");
}

下面是各个功能函数以及该功能涉及的数据结构操作函数(按操作序号排序):

1.录入数据:

//录入数据.cpp。值得注意的是,这个系统用的是文件本保存数据,相当于用文件本代替数据库,进而简化系统的理解难度。已经学习数据库的读者可以自行修改代码代换成数据库。
//这里的录入数据,指的是从文件本中逐行读取数据,然后添加到数据链表上以便进一步操作,退出系统同理,将数据链表写入文件本中,直接覆盖原数据,从而达到修改保存的目的。
#include "head.h"

void luru(ADDR *&h)//函数这里*&h中有讲究,有&则代表将改变数据链表的内容,无&则只是读取,读者自行体会
{
    int pd;
    FILE *fp;//定义文件本指针
    if((fp=fopen("D://学生信息数据.txt","r"))==NULL)//这里判断文件是否存在
    {
        printf("文件不存在。\n");
        printf("跳回主菜单!\n");
        getchar();
        system("cls");
        return ;
    }
    while(fscanf(fp,"%d",&pd)!=EOF&&pd==1)//逐行读取文件本数据
    {
        ListInsert2(h,h->length,fp);//将数据写入数据链表
    }
    fclose(fp);//关闭流
    printf("\n\t录入成功,按回车键继续\n");
    getchar();
    getchar();
    system("cls");
}

bool ListInsert2(ADDR *&L,int &i,FILE *&fp)//这就是简单的节点插入链表的操作
{
    i++;
    int j=0;
    ADDR *p=L,*s;
    while(j<i-1&&p!=NULL)//找到链表插入点
    {
        j++;
        p=p->next;
    }
    if(p==NULL)
        return false;
    else
    {
        s=(ADDR *)malloc(sizeof(ADDR));
        fscanf(fp,"%lld %s %s %s %s %d %d %d",&s->student_number,&s->name,&s->gender,&s->academy,&s->major,&s->English,&s->computer,&s->math);//这里比较讲究,根据数据对齐转换为节点的各个属性成员
        s->total_points=s->English+s->computer+s->math;//算个总分
        s->next=p->next;//插入
        p->next=s;
        return true;
    }
}

2.删除数据:

//删除数据.cpp。删除比较简单,根据学号找到对应的数据,执行单链表的删除操作即可。
#include "head.h"

void deletedata(ADDR *&h)
{
    int z;
    do
    {
        printf("\t请输入学生学号:");
        long long ID;
        scanf("%lld",&ID);
        int i=LocateElem(h,ID);//查找该学号的节点位置
        while(i==0)
        {
            printf("\t该学生学号不存在!\n");
            printf("\t请输入正确的学生学号:");
            scanf("%lld",&ID);
            i=LocateElem(h,ID);
        }
        printf("\t该学生数据如下如下:\n\t");
        GetElem(h,i);
        printf("\t是否执行删除操作?(确定输入1,取消输入0)");
        int j;
        scanf("%d",&j);
        if(j==1)
        {
            bool pd=ListDelete(h,i);//单链表的删除节点操作
            if(pd) printf("\t删除成功。\n");
            else printf("\t删除失败。\n");
        }
        printf("\t是否继续执行删除操作(输入1为继续删除,输入0结束删除系统):");
    }while(scanf("%d",&z)!=EOF&&z==1);
    system("cls");
}

bool ListDelete(ADDR *&L,int i)//单链表的删除节点操作
{
    int j=0;
    ADDR *p=L,*q;
    while (j<i-1&&p!=NULL)//找到要删除的节点
    {
        j++;
        p=p->next;
    }
    if(p==NULL)
        return false;
    else
    {
        q=p->next;
        if(q==NULL)
            return false;
        p->next=q->next;
        free(q);
        L->length--;
        return true;
    }
}

3.增添数据:

//增添数据.cpp。单链表的增添节点操作
#include "head.h"

void add_data(ADDR *&h)
{
    int z;
    do
    {
        bool pd=ListInsert(h,h->length);
        if(pd) printf("\t增添成功!\n");
        else printf("\t增添失败!\n");
        printf("\t是否继续执行增添操作(输入1为继续增添,输入0返回主菜单):");
    }while(scanf("%d",&z)!=EOF&&z==1);
    system("cls");
}

bool ListInsert(ADDR *&L,int &i)
{
    i++;
    int j=0;
    ADDR *p=L,*s;
    while(j<i-1&&p!=NULL)
    {
        j++;
        p=p->next;
    }
    if(p==NULL)
        return false;
    else
    {
        s=(ADDR *)malloc(sizeof(ADDR));
        printf("\t请输入录入学生的学号:");
        scanf("%lld",&s->student_number);
        printf("\t请输入录入学生的姓名:");
        scanf("%s",&s->name);
        printf("\t请输入录入学生的性别:");
        scanf("%s",&s->gender);
        printf("\t请输入录入学生的学院:");
        scanf("%s",&s->academy);
        printf("\t请输入录入学生的专业班级:");
        scanf("%s",&s->major);
        printf("\t请输入录入学生的外语成绩:");
        scanf("%d",&s->English);
        printf("\t请输入录入学生的计算机成绩:");
        scanf("%d",&s->computer);
        printf("\t请输入录入学生的数学成绩:");
        scanf("%d",&s->math);
        s->total_points=s->English+s->computer+s->math;
        s->next=p->next;
        p->next=s;
        return true;
    }
}

4.查询数据:

//查询数据.cpp。这里分了学号查询和姓名查询两种方式,分别是整数查询和字符串查询,比较简单,不多解释。
#include "head.h"

void find_data(ADDR *&h)
{
    int z;
    do
    {
        printf("\t【1】学号查询         【2】姓名查询\n");
        printf("\t请选择你要进行的查询操作(1~2):");
        int i;
        scanf("%d",&i);
        while(i!=1&&i!=2)
        {
            printf("\t输入有误,请重新输入。");
            printf("\t请选择你要进行的查询操作(1~2):");
            scanf("%d",&i);
        }
        if(i==1)
        {
            long long ID;
            printf("\t请输入要查询学生的学号:");
            scanf("%lld",&ID);
            int i;
            i=LocateElem(h,ID);
            if(i==0) printf("\t不存在该学生学号,查找失败\n");
            else
            {
                printf("\t该学生的基本信息如下\n\t(格式为:学号 姓名 性别 学院 专业班级 外语成绩 计算机成绩 数学成绩 三科总分):\n");
                GetElem(h,i);
            }
        }
        else
        {
            printf("\t请输入要查询学生的姓名:");
            char name[20];
            scanf("%s",&name);
            int j;
            j=LocateElem2(h,name);
            if(j==0) printf("\t不存在该学生姓名,查找失败\n");
            else
            {
                printf("\t该学生的基本信息如下(格式为:学号 姓名 性别 学院 专业班级 外语成绩 计算机成绩 数学成绩 三科总分):\n");
                GetElem(h,j);
            }
        }
        printf("\t是否继续执行查询操作(输入1为继续查询,输入0结束查询系统):");
    }while(scanf("%d",&z)!=EOF&&z==1);
    system("cls");
}

bool GetElem(ADDR *L,int i)
{
    int j=0;
    ADDR *p=L;
    while(j<i&&p!=NULL)
    {
        j++;
        p=p->next;
    }
    if(p==NULL)
        return false;
    else
    {
        printf("\t%lld %s %s %s %s %d %d %d %d\n",p->student_number,p->name,p->gender,p->academy,p->major,p->English,p->computer,p->math,p->total_points);
        return true;
    }
}
int LocateElem(ADDR *L,long long e)
{
    int i=1;
    ADDR *p=L->next;
    while(p!=NULL&&p->student_number!=e)
    {
        p=p->next;
        i++;
    }
    if(p==NULL)
        return (0);
    else
        return (i);
}

int LocateElem2(ADDR *L,char s[])
{
    int i=1;
    ADDR *p=L->next;
    while(p!=NULL&&strcmp(p->name,s)!=0)
    {
        p=p->next;
        i++;
    }
    if(p==NULL)
        return (0);
    else
        return (i);
}

5.排序数据:

//排序数据.cpp。排序这的代码比较简洁,但用到了C++的STL(标准模板库)。用了优先队列和运算符重载,不懂可以百度。
#include "head.h"

void sort_data(ADDR *&h)
{
    printf("\t以下是学生总分排名:\n");
    ADDR *s=h;
    SNode g;
    priority_queue<SNode>q;//定义优先队列
    for(int i=0;i<h->length;i++)//将节点逐个压入优先队列中
    {
        s=s->next;
        g.student_number=s->student_number;
        strcpy(g.name,s->name);
        strcpy(g.gender,s->gender);
        strcpy(g.academy,s->academy);
        strcpy(g.major,s->major);
        g.English=s->English;
        g.computer=s->computer;
        g.math=s->math;
        g.total_points=s->total_points;
        q.push(g);
    }
    SNode p;
    while(!q.empty())//再逐个输出即可
    {
        p=q.top();
        printf("\t%lld %s %s %s %s %d %d %d %d\n",p.student_number,p.name,p.gender,p.academy,p.major,p.English,p.computer,p.math,p.total_points);
        q.pop();
    }
    printf("\n\t按回车跳回主菜单!\n");
    getchar();
    getchar();
    system("cls");
}

6.统计数据:

//统计数据.cpp。这里分为学院人数统计和班级人数统计两种,代码较简单,读者可自行理解。
#include "head.h"

void statistics(ADDR *&h)
{
    char academy[100][20]={0};
    int vis[100]={0};
    int sum=0;
    ADDR *s=h;
    while(s->next!=NULL)
    {
        s=s->next;
        int j;
        for(j=0;j<sum;j++)
        {
            if(strcmp(academy[j],s->academy)==0)
                break;
        }
        if(j==sum)
        {
            strcpy(academy[sum],s->academy);
            vis[sum]=1;
            sum++;
        }
        else
        {
            vis[j]++;
        }
    }
    printf("\n\t学院人数统计:\n");
    for(int i=0;i<sum;i++)
    {
        printf("\t%s\t",academy[i]);
        printf("\t %d 人。\n",vis[i]);
    }
    char major[100][20]={0};
    int vis2[100]={0};
    int sum2=0;
    ADDR *s2=h;
    while(s2->next!=NULL)
    {
        s2=s2->next;
        int k;
        for(k=0;k<sum2;k++)
        {
            if(strcmp(major[k],s2->major)==0)
                break;
        }
        if(k==sum2)
        {
            strcpy(major[k],s2->major);
            vis2[sum2]=1;
            sum2++;
        }
        else
        {
            vis2[k]++;
        }
    }
    printf("\n\t班级人数统计:\n");
    for(int i=0;i<sum2;i++)
    {
        printf("\t%s\t",major[i]);
        printf("\t %d 人。\n",vis2[i]);
    }
    printf("\n\t按回车跳回主菜单!\n");
    getchar();
    getchar();
    system("cls");
}

7.修改数据:

//修改数据.cpp。前一步是查找该节点,后一步为修改相关属性成员,读者可自行理解。
#include "head.h"

void modification(ADDR *&h)
{
    int z;
    do
    {
        printf("\t请输入修改学生的学号:");
        long long ID;
        scanf("%lld",&ID);
        int i;
        i=LocateElem(h,ID);
        while(i==0)
        {
            printf("\t不存在该学生学号!\n");
            printf("\t请输入正确的学生学号:");
            scanf("%lld",&ID);
            i=LocateElem(h,ID);
        }
        printf("\t该学生基本信息如下:\n");
        GetElem(h,i);
        printf("\t是否执行修改操作?(确定输入1,取消输入0)");
        int j;
        scanf("%d",&j);
        if(j==1)
        {
            bool pd=modification_data(h,i);
            if(pd) printf("\t修改成功。\n");
            else printf("\t修改失败。\n");
        }
        printf("\t是否继续执行修改操作(输入1为继续修改,输入0结束修改系统):");
    }while(scanf("%d",&z)!=EOF&&z==1);
    system("cls");
}

bool modification_data(ADDR *&h,int i)
{
    ADDR *s=h;
    for(int j=0;j<i;j++)
    {
        s=s->next;
    }
    printf("\t(1)姓名 (2)性别 (3)学院 (4)专业班级\n\t(5)外语 (6)计算机 (7)数学\n");
    printf("\t请选择你要修改该学生的哪一项信息:");
    int d;
    scanf("%d",&d);
    while(d<1||d>7)
    {
        printf("\t输入有误,请重新输入(1~7):");
        scanf("%d",&d);
    }
    switch(d)
    {
        case 1:
        {
            printf("\t请输入修改的姓名:");
            scanf("%s",&s->name);
            break;
        }
        case 2:
        {
            printf("\t请输入修改的性别:");
            scanf("%s",&s->gender);
            break;
        }
        case 3:
        {
            printf("\t请输入修改的学院:");
            scanf("%s",&s->academy);
            break;
        }
        case 4:
        {
            printf("\t请输入修改的专业班级:");
            scanf("%s",&s->major);
            break;
        }
        case 5:
        {
            printf("\t请输入修改的英语成绩:");
            scanf("%d",&s->English);
            break;
        }
        case 6:
        {
            printf("\t请输入修改的计算机成绩:");
            scanf("%d",&s->computer);
            break;
        }
        case 7:
        {
            printf("\t请输入修改的数学成绩:");
            scanf("%d",&s->math);
            break;
        }
    }
    s->total_points=s->English+s->computer+s->math;
    return true;
}

8.输出数据(该功能在主函数.cpp和公用函数.cpp中):

//公用函数.cpp。
#include "head.h"

void InitList(ADDR *&L)
{
    L=(ADDR *)malloc(sizeof(ADDR));
    L->next=NULL;
}

void DispList(ADDR *L)
{
    ADDR *s=L->next;
    while(s!=NULL)
    {
        printf("\t%lld %s %s %s %s %d %d %d %d\n",s->student_number,s->name,s->gender,s->academy,s->major,s->English,s->computer,s->math,s->total_points);
        s=s->next;
    }
    printf("\n");
}

void DestroyList(ADDR *&L)//删除数据链表,释放空间
{
    ADDR *p=L,*q=p->next;
    while (q!=NULL)
    {
        free(p);
        p=q;
        q=p->next;
    }
    free(p);
}

9.退出并保存:

//保存数据.cpp。这里是第九项操作退出系统的前缀步骤,把修改完的数据链重写覆盖到文件本里,实现数据的更新。
#include "head.h"

void save(ADDR *&h)
{
    printf("\t保存中...\n");
    FILE *fp;
    if((fp=fopen("E://学生信息数据 .txt","w"))==NULL)
    {
        printf("\t读取磁盘文件失败。\n");
        return ;
    }
    read_in(h,fp);
    fclose(fp);
    printf("\t保存成功!\n");
}

void read_in(ADDR *L,FILE *&fp)
{
    int fd = fileno(fp);
    ftruncate(fd,0);
    rewind(fp);
    ADDR *s=L->next;
    while(s!=NULL)
    {
        fprintf(fp,"1 %lld %s %s %s %s %d %d %d\n",s->student_number,s->name,s->gender,s->academy,s->major,s->English,s->computer,s->math);
        s=s->next;
    }
    printf("\n");
}

下面附带一份测试数据(将测试数据复制粘贴到D://学生信息数据.txt中即可):

1 52413404201 北乔峰 男 信息学院 软件工程2班 90 98 94
1 52413404202 南慕容 男 信息学院 软件工程2班 93 94 99
1 52413404203 霍建华 男 信息学院 软件工程2班 92 98 93
1 52413404241 匹马呀 男 信息学院 软件工程2班 100 100 100
1 52413403468 方冰冰 女 经贸学院 经济管理3班 98 87 46
1 52413404242 周星星 女 信息学院 软件工程2班 95 94 100
1 52413404141 陈正城 男 信息学院 软件工程1班 97 97 97
1 52413404888 段正淳 男 金庸学院 挖掘机1班 97 97 64
1 52413404211 小龙女 女 信息学院 软件工程2班 97 98 98
1 52413404240 全真子 男 信息学院 软件工程2班 95 94 93
1 52413404238 剁剁手 男 边锋学院 国战专业 59 86 64
1 52413404241 当阳啊 男 信息学院 软件工程2班 99 100 100

下面是部分测试结果:

如有不清楚的,可以评论留言。

  • 66
    点赞
  • 361
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值