操作流程

创建文件

创建管理类

​ 管理类负责的内容如下:

  • 提供与用户的沟通菜单界面

  • 实现对职工增删改查的操作

  • 数组数据与文件的读写交互

菜单功能实现

在StudentManager.h中定义ShowMenu()函数在StudentManager.cpp中实现显示菜单功能,便于与用户交互,利用序号将所有功能显示出来,便于用户选择以及,进行后期的使用。

代码如下

void StudentManager::Show_Menu()
{
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
cout << "~~~~~~~~~~~~~~~~学生学籍管理系统~~~~~~~~~~~~~~~~" << endl;
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
cout << "******************(0)退出系统*****************" << endl;
cout << "******************(1)录入学生*****************" << endl;
cout << "******************(2)显示学籍*****************" << endl;
cout << "******************(3)删除学生*****************" << endl;
cout << "******************(4)修改学生*****************" << endl;
cout << "******************(5)查找学生*****************" << endl;
cout << "******************(6)学生排序*****************" << endl;
cout << "******************(7)分类显示*****************" << endl;
cout << "******************(8)清空系统*****************" << endl;
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
}

退出功能

为各种功能提供接口

在main函数中为管理操作的函数提供接口,创建实例对象,调用对象内成员函数

实现代码

int main()
{ StudentManager stu;
int chioce;
while (true)
{
system("color B1");//美化控制台
//显示菜单
stu.Show_Menu();
cout << "请输入您的选择:";
cin >> chioce;
switch (chioce)
{
case 0:stu.Exit_System();//退出系统
break;
case 1:stu.Add_Student();//录入学生
break;
case 2:stu.ShowStudent();//显示学籍
break;
case 3:stu.DeleteStudent();//删除学生
break;
case 4:stu.ModStudent();//修改学生
break;
case 5:stu.FindStudent();//查找学生
break;
case 6:stu.SortStudent();//学生排序
break;
case 7:stu.ClassifyStudent();//分类显示
break;
case 8:stu.CleanStudent();//清空系统
break;
default://
system("cls");
break;
}
system("pause"); } return 0;
}

退出功能实现

在StudentManager.h中定义Exit_System();函数

在StudentManager.cpp中实现函数功能,利用exit(0);实现程序的退出操作

代码实现如下:

void StudentManager::Exit_System()
{
cout << "欢迎下次使用" << endl;
system("pause");
exit(0);
}

创建学生类

创建大一类

先创建学生类作为父类,然后定义各种成员属性

大一类继承学生抽象类,并重写父类中的重虚函数

创建头文件Grade01.h和源文件Grade.cpp

代码实现如下

Grade01.h

#pragma once
#include"Student.h" class Grade01:public Student
{
public: Grade01(int id, string name, int grade);
void Show_Info();//显示个人信息
string Get_Grade();//获取年级名称
};

Grade01.cpp

#include"Grade01.h"

Grade01::Grade01(int id,string name,int grade)
{
this->m_id = id;
this->m_name = name;
this->m_grade = grade;
}
void Grade01::Show_Info()//显示个人信息
{
cout << "学号:" << this->m_id << " "
<< "姓名:" << this->m_name << " "
<< "年级:" << this->Get_Grade() << endl;
}
string Grade01::Get_Grade()//获取年级名称
{
return (string)"大一";
}

创建大二类

与大一类上述代码相同不再赘述

创建大三类

与大一类上述代码相同不再赘述

创建大四类

与大一类上述代码相同不再赘述

添加学生

在StudentManager.h中添加属性以及成员函数

根据学生的人数加上添加后的人数,开辟一块新的空间记录数据

系统整体利用指针数组实现数据的临时保存,最终与文件的操作配合使用,使数据转存到文件中

	//记录人数
int Student_Num;
//学生数组的指针
Student** Student_Array;//指针数组用来存Student* 的数组(Student*)* Student_Array;

在StudentManager.cpp中构造函数中初始化

	//初始化人数
this->Student_Num = 0;
//初始化数组指针
this->Student_Array = NULL;

在StudentManager.cpp中实现成员函数

void StudentManager::Add_Student()
{
cout << "请输入添加学生数量" << endl;
int addnum;
cin >> addnum;
if (addnum > 0)
{
//计算新空间大小
int newsize = this->Student_Num + addnum;
//开辟空间
Student** newspace = new Student * [newsize];
//将源空间的内容存放到新空间下
if (this->Student_Array != NULL)
{
for (int i = 0; i < this->Student_Num; i++)
{
newspace[i] = this->Student_Array[i];
}
}
//输入新数据
for (int i = 0; i < addnum; i++)
{
int id;
string name;
int select;
cout << "请输入第" << i + 1 << "个学生学号" << endl;
cin >> id;
cout << "请输入第" << i + 1 << "个学生姓名" << endl;
cin >> name;
cout << "请输入第" << i + 1 << "个学生年级编号" << endl;
cout << "1、大一" << endl;
cout << "2、大二" << endl;
cout << "3、大三" << endl;
cout << "4、大四" << endl;
cin >> select;
Student* student = NULL;
switch (select)
{
case 1://大一
student = new Grade01(id, name, 1);
break;
case 2://大2
student = new Grade02(id, name, 1);
break;
case 3://大3
student = new Grade03(id, name, 1);
break;
case 4://大4
student = new Grade04(id, name, 1);
break;
default:
break;
} newspace[this->Student_Num + i] = student;
}
//释放原有空间
delete[]this->Student_Array;
//更新空间指向
this->Student_Array = newspace;
//更新学生个数
this->Student_Num = newsize;
//提示
cout << "添加成功" << addnum << "个学生" << endl; }
else {
cout << "输入有误" << endl;
}
system("pause");
system("cls");
}

保存文件

void StudentManager::Save()
{
ofstream ofs;
ofs.open(FILENAME, ios::out);//以写文件的方式打开文件
for (int i = 0; i < this->Student_Num; i++)
{
ofs << this->Student_Array[i]->m_id << " "
<< this->Student_Array[i]->m_name << " "
<< this->Student_Array[i]->m_grade << " " << endl;
}
ofs.close();
}

初始化学生

在初始化学生之前,要判断学生文件状态,分为三种情况

1、第一次使用文件未创建

2、文件存在,但是为空文件

3、文件和数据正常存在

首先在StudentManager.h中添加标志文件是否为空的标志

若为空文件,或者文件不存在,则该bool类型的值返回true

bool FileIsEmpty;

修改StudentManager.cpp中的构造函数代码

StudentManager::StudentManager()
{ ifstream ifs;
ifs.open(FILENAME, ios::in);
//文件不存在情况
if (!ifs.is_open())
{
cout << "文件不存在" << endl;
this->Student_Num = 0;//初始化人数为零
this->FileIsEmpty = true;//标志文件为空
this->Student_Array = NULL;//初始化数组为空
ifs.close();//关闭文件
return;
}
//文件存在,并且没有记录
char ch;
ifs >> ch;
if (ifs.eof())
{
cout << "文件为空" << endl;
this->Student_Num = 0;
this->FileIsEmpty = true;
this->Student_Array = NULL;
ifs.close();
return;
}
int num = this->get_StudentNum();
cout << "职工个数为:" << num << endl;
this->Student_Num = num;
//根据职工数创建数组
this->Student_Array = new Student * [this->Student_Num];
this->InitStudent();
}

如果文件不存在,则初始化文件

文件在不存在,或者为空的情况下,判断文件是否为空的标志都为真

成功添加学生信息后更改文件不为空

初始化文件

初始化Student* 类型的指针数组,将Student类型的地址存到*Student****中

在StudentManager.cpp中实现

void StudentManager::InitStudent()
{
ifstream ifs;
ifs.open(FILENAME, ios::in);
int id;
string name;
int Grade;
int index=0;
while (ifs >> id && ifs >> name && ifs >> Grade)
{
Student* student = NULL;//根据年级创建student*的对象
if (id == 1)
{
student = new Grade01(id, name, Grade);
}else if(id==2)
{
student = new Grade02(id, name, Grade);
}
else if (id == 3)
{
student = new Grade03(id, name, Grade);
}
else
{
student = new Grade04(id, name, Grade);
}
//存放在数组中
this->Student_Array[index] = student;
index++; }
}

显示学生

void StudentManager::ShowStudent()
{
if (this->FileIsEmpty)
{
cout << "文件为空或者不存在" << endl;
}
else
{
for (int i = 0; i < this->Student_Num; i++)
{
//利用多态调用接口
this->Student_Array[i]->Show_Info();
}
}
system("pause");
system("cls");
}

删除学生

删除学生之前判断其是否存在

如果为空或者不存在,返回-1,如果存在,返回其下标

在StudentManager.cpp中实现

根据成员属性匹配的到数组的下标,便于后续索引类型的操作进行

int StudentManager::IsExist(int id)
{
int index = -1;
for (int i = 0; i < this->Student_Num; i++)
{
if (this->Student_Array[i]->m_id == id)
{
index = i;
break;
}
}
return index;
}

删除,实现按照学号删除

void StudentManager::DeleteStudent()
{
if (this->FileIsEmpty)
{
cout << "文件不存在或者记录为空" << endl;
}
else
{
cout << "请输入要删除的学生学号" << endl;
int id = 0;
cin >> id;
int index = this->IsExist(id);
if (index != -1)
{
for (int i = index; i < this->Student_Num - 1; i++)
{
this->Student_Array[i] = this->Student_Array[i + 1];
}
this->Student_Num--;
this->Save();//删除后同步数据到文件
cout << "删除成功" << endl;
}
else
{
cout << "删除失败,未找到该职工" << endl;
}
}
system("pause");
system("cls");
}

查找学生

按照学生编号,按照学生姓名

void StudentManager::FindStudent()
{
if (this->FileIsEmpty)
{
cout << "文件不存在或者记录为空!" << endl;
}
else
{
cout << "请输入查找的方式:" << endl;
cout << "1、按学号查找" << endl;
cout << "2、按姓名查找" << endl; int select = 0;
cin >> select;
if (select == 1)//按照学号查找
{
int id;
cout << "请输入查找的学号" << endl;
cin >> id;
int ret = this->IsExist(id);
if (ret != -1)
{
cout << "查找成功,该学生信息如下" << endl;
this->Student_Array[ret]->Show_Info();
}
else
{
cout << "查找失败,查无此人" << endl;
}
}
else if (select == 2)//按姓名查找
{
string name;
cout << "请输入查找的姓名" << endl;
cin >> name;
bool flag = false;//查找到的标志
for (int i = 0; i < this->Student_Num; i++)
{
if (this->Student_Array[i]->m_name == name)
{
cout << "查找成功,信息如下" << endl;
flag = true;
this->Student_Array[i]->Show_Info();
}
}
if (flag == false)
{
cout << "查找失败,查无此人!!" << endl;
}
}
else
{
cout << "输入选项有误" << endl;
}
}
system("pause");
system("cls");
}

修改学生信息

按照编号对职工信息保存修改

利用IsExist函数获取学生数组元素下标,然后对应进行修改,记录保存

void StudentManager::ModStudent()
{
if (this->FileIsEmpty)
{
cout << "文件不存在,或记录为空" << endl;
}
else
{
cout << "请输入要修改的学生学号" << endl;
int id;
cin >> id;
int ret = this->IsExist(id);
if (ret != -1)
{
delete this->Student_Array[ret];
int newid = 0;
string newname = "";
int select = 0;
cout << "查到" << id << "号学生,请输入新学号" << endl;
cin >> newid;
cout << "请输入新姓名" << endl;
cin >> newname;
cout << "请输入年级" << endl;
cout << "1、大一" << endl;
cout << "2、大二" << endl;
cout << "3、大三" << endl;
cout << "4、大四" << endl;
cin >> select;
Student* student = NULL;
switch (select)
{
case 1://大一
student = new Grade01(newid, newname, 1);
break;
case 2://大2
student = new Grade02(newid, newname, 2);
break;
case 3://大3
student = new Grade03(newid, newname, 3);
break;
case 4://大4
student = new Grade04(newid, newname, 4);
break;
default:
break;
}
//更新数据到数组中
this->Student_Array[ret] =student;
cout << "修改成功" << endl;
//保存文件
this->Save(); }
else
{
cout << "修改失败,查无此人" << endl;
}
system("pause");
system("cls");
}
}

按学号排序

排序采用冒泡排序,前后两两比较,根据排序要求进行交换元素位置,达到排序目的

void StudentManager::SortStudent()
{
if (this->FileIsEmpty)
{
cout << "文件不存在或者记录为空" << endl;
system("pause");
system("cls"); }
else
{
cout << "请选择排序方式: " << endl;
cout << "1、按学号进行升序" << endl;
cout << "2、按学号进行降序" << endl; int select = 0;
cin >> select; for (int i = 0; i < this->Student_Num; i++)
{
int minOrmax = i;
for (int j = i + 1; j < this->Student_Num; j++)
{
if (select == 1)
{
if (this->Student_Array[minOrmax]->m_id > this->Student_Array[j]->m_id)
{
minOrmax = j;
}
}
else
{
if (this->Student_Array[minOrmax]->m_id < this->Student_Array[j]->m_id)
{
minOrmax = j;
}
}
}
if (i != minOrmax)
{
Student* temp = this->Student_Array[i];
this->Student_Array[i] = this->Student_Array[minOrmax];
this->Student_Array[minOrmax] = temp;
}
}
cout << "排序成功" << endl;
this->Save();
}
}

按年级分类查看

遍历数组,匹配相应年级相应代码,然后输出每个年级下面的学生分类

void StudentManager::ClassifyStudent()
{
cout << "大一:" << endl;
for (int i = 0; i < this->Student_Num; i++)
{
if (this->Student_Array[i]->m_grade == 1)
{
this->Student_Array[i]->Show_Info(); }
}
cout << endl;
cout << "大二:" << endl;
for (int i = 0; i < this->Student_Num; i++)
{
if (this->Student_Array[i]->m_grade ==2)
{
this->Student_Array[i]->Show_Info(); }
}
cout << endl;
cout << "大三:" << endl;
for (int i = 0; i < this->Student_Num; i++)
{
if (this->Student_Array[i]->m_grade == 3)
{
this->Student_Array[i]->Show_Info(); }
}
cout << endl;
cout << "大四:" << endl;
for (int i = 0; i < this->Student_Num; i++)
{
if (this->Student_Array[i]->m_grade ==4)
{
this->Student_Array[i]->Show_Info(); }
}
system("pause");
system("cls");
}

清空数据

首先确认是否清空

然后打开文件

打开模式 ios::trunc 如果存在删除文件并重新创建

关闭文件

判断,如果指针数组不为空,那么将里面的指针释放干净,成员个数更新为零,将指针数组置为空,更新文件为空的标志。

void StudentManager::CleanStudent()
{
cout << "确认清空?" << endl;
cout << "1、确认" << endl;
cout << "2、返回" << endl;
int select = 0;
cin >> select;
if (select == 1)
{
//打开模式ios::trunc如果存在就删除文件并重新创建
ofstream ofs(FILENAME, ios::trunc);
ofs.close();
if (this->Student_Array != NULL)
{
for (int i = 0; i < this->Student_Num; i++)
{
if (this->Student_Array[i] != NULL)
{
delete this->Student_Array[i];
}
}
this->Student_Num = 0;
delete[] this->Student_Array;
this->Student_Array = NULL;
this->FileIsEmpty = true;
}
cout << "清空成功" << endl;
}
system("pause");
system("cls");
}

项目代码

链接:https://pan.baidu.com/s/1Mo6uVRuZRMmNAYL0bVX8kw

提取码:s99z

C++实现控制台学生学籍管理系统的更多相关文章

  1. [C语言练习]学生学籍管理系统

    /** * @copyright 2012 Chunhui Wang * * wangchunhui@wangchunhui.cn * * 学生学籍管理系统(12.06) */ #include &l ...

  2. “石家庄铁道大学软件工程系学生学籍管理系统2019版”java小程序制作分享

    首先附上完整代码: import java.util.Scanner; public class SocreInformation { public SocreInformation(){}; pub ...

  3. Java 石家庄铁道大学软件工程系 学生学籍管理系统 2019 版

    本系统的作用是简单实现一些学生成绩管理操作:录入,修改,绩点计算,以及系统退出等. 首先建一个主函数实现界面的实现,然后建一个数据类用来定义存放数据.之后建立一个工具类,用来实现所有要进行的操作.首先 ...

  4. Qt实现学生学籍管理系统(文件存储)

    记录 19:53 2019-07-30 在小学期学c++做完课设后萌生了把写完的课设放在博客上的想法,于是,我第一篇博客诞生了. 22:32:19 2019-07-30 下棋 16:04:56 201 ...

  5. 【C】C语言大作业——学生学籍管理系统

    文章目录 学生管理系统 界面 主界面 登陆界面 注册界面 管理界面 学生界面 退出界面 链接 注意 学生管理系统 学C语言时写的一个大作业,弄了一个带图形界面的,使用的是VS配合EasyX图形库进行实 ...

  6. 【C语言期末实训】学生学籍管理系统

    目录: 一,设计要求 ,总体要求: ,具体功能: 二,设计框架 三,程序代码 ,声明函数和头文件 ,声明结构体 ,声明全局变量 ,主体启动函数 ,主菜单函数 ,创建学生档案函数 ,编辑学生档案函数 , ...

  7. 还是把一个课程设计作为第一篇文章吧——学生学籍管理系统(C语言)

    #include <stdio.h> #include<stdlib.h> #include<string.h> typedef struct student { ...

  8. JAVA之学生信息管理系统

    StudentManager系统 系统的数据: 变量 stunumber 为字符串类型 String,用于存储学生的学号(有 8 位数字组成) 变量 name 为字符串类型 String,用于存储学生 ...

  9. JAVA语言课堂测试01源代码(学生成绩管理系统)

    package 考试; /*信1807-8 * 20183798 * 向瑜 */ import java.util.Scanner; //ScoreInformation 类 class ScoreI ...

随机推荐

  1. Github 获取仓库的releases API

    API 文档 example: 这将获取所有的版本 https://api.github.com/repos/januwA/flutter_anime_app/releases 最新版本: https ...

  2. java初学者必看之构造方法详细解读

    java初学者必看之构造方法详细解读 构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是在调用构造方法. 格式 public 类名称(参数类型 参数名称){ 方法体 } 注 ...

  3. 【SpringMVC】 4.2 异常处理

    SpringMVC学习记录 注意:以下内容是学习 北京动力节点 的SpringMVC视频后所记录的笔记.源码以及个人的理解等,记录下来仅供学习 第4章 SpringMVC 核心技术 4.2异常处理   ...

  4. Docker Tips: 关于/var/run/docker.sock

    本文转载自Docker Tips: 关于/var/run/docker.sock 导语 你可能已经运行过docker hub上的container并且注意到其中的一些需要绑定挂载(mount)/var ...

  5. scala:函数作为值或参数进行传递、作为返回值进行返回

    @ 目录 函数可以作为值进行传递 函数可以作为参数进行传递 函数可以作为返回值进行返回 什么是匿名函数 函数可以作为值进行传递 语法var f = 函数名 _ 如果明确了变量的数据类型,那么下划线可以 ...

  6. 1.3 PHP+MYSQL+APACHE配置(序)

    本节对服务器端web服务进行配置.事实上,对于配置这个环境(WAMP)网上还是有很多教程的,大家可以通过网上的教程完成配置,也不必拘泥于本文.甚至网上有免费的服务器端软件可以选择,比如著名的phpst ...

  7. Spring-04 Bean的自动装配

    Spring-04 Bean的自动装配 Bean的自动装配 1.自动装配说明 自动装配是使用spring满足bean依赖的一种方法. spring会在应用上下文中为某个bean寻找其依赖的bean. ...

  8. Linux磁盘分区格式化和扩容

    Note:根据各系统上磁盘的类型不同,磁盘命名规则也会不同:例如/dev/xvd,/dev/sd,/dev/vd,/dev/hd 目录 磁盘格式化 MBR格式 GPT分区 磁盘扩容 MBR格式扩容 G ...

  9. ISC BIND9 - 最详细、最认真的从零开始的BIND 9 服务讲解

    DNS and BIND 服务的搭建说明 目录 目录 DNS and BIND 服务的搭建说明 1. 背景 1.1 DNS 1.2 FQDN 1.3 BIND 1.4 本文中搭建模拟DNS服务网络虚拟 ...

  10. pytorch(15)损失函数

    损失函数 1. 损失函数概念 损失函数:衡量模型输出与真实标签的差异 \[损失函数(Loss Function): Loss = f(\hat y,y) \] \[代价函数(Cost Function ...