学生管理系统(C++,控制台,文件读取,姓名排序)
Posted 李子树呢
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学生管理系统(C++,控制台,文件读取,姓名排序)相关的知识,希望对你有一定的参考价值。
这是一个用C++写的控制台程序,利用简单的菜单实现学生信息的管理。
简图如下所示:
菜单栏:
查询数据:
修改数据:
打印数据:
以下是添加了一些学生信息的进行一些操作的结果:
除了上面所展示的功能以外,还可以将所有的学生信息保存到一个txt文件中,或者将一个文件里面的学生信息读取进来,当然,读取的文件需要按照保存文件的格式进行排列。
在刚开始的时候我认为中文排序是最困难的,在经过很多网上资料的翻阅之后,终于找到了一个可行的方法。你可以百度一下pinyin.c了解一下这种中文排序的方法,这个文件里面是一个char类型的数组,有人将unicode码中从小到大的所有中文汉字的首字母依次存储到这个数组中,这意味着我们只需要获取这个中文汉字的unicode码就可以得到它的首字母,此时你就使用排序算法对字母转化而来的数值(ASCII码)进行排序就好了。由于我们平时使用的保存姓名都是用的字符串string类型,需要获得unicode码,还需要将它转化为wstring类型之后才能获取,这里我直接找到了一个函数将它转化。
下面我们还是来查看一下源代码:我是使用单链表实现的,不仅实现了一个链表类,该类还包含了一个简单的结构——节点。总有有三个文件
**⒈Linked_List.h **
#ifndef LINKED_LIST
#define LINKED_LIST
#include<iostream>
#include<iomanip>
#include<string>
#include <cstdlib>
#include<fstream>
using namespace std;
#define HANZI_START 19968 //unicode码的中文汉字起始位置就是19968
#define HANZI_COUNT 20902 //unicode码中包含了20902个中文汉字,所以需要这么大一个数组才能存储它们所有的首字母
wstring String_To_WString(const string &s); //将string转化为wstring类型
int Get_First_Pinyin(string name); //从数组中提取中文汉字的首字母
struct Node //保存学生信息的一个节点
string Name; //姓名
int Student_ID; //学号
string Gender; //性别
int Age; //年龄
string Class; //班级
string Health_Status; //健康状况
Node *Next_Student; //指向下一个节点的指针
Node() //默认构造函数,实现成员的初始化
Name = "NULL";
Student_ID = NULL;
Gender = "NULL";
Age = NULL;
Class = "NULL";
Health_Status = " NULL";
Next_Student = NULL;
Node(string name) //利用姓名创建学生信息的构造函数
Name = name;
cout << "请输入"<<name<<"的学号:";
cin >> Student_ID;
cout << "请输入" << name << "的性别:";
cin >> Gender;
cout << "请输入" << name << "的年龄:";
cin >> Age;
cout << "请输入" << name << "的班级:";
cin >>Class;
cout << "请输入" << name << "健康状况:";
cin >> Health_Status;
Next_Student = NULL;
Node(string name,int student_id,string gender,int age,string Class,string health_status)
//传入所有信息,直接创建一个学生信息
Name = name;
Student_ID = student_id;
Gender = gender;
Age = age;
this->Class = Class;
Health_Status = health_status;
Next_Student = NULL;
;
class Linked_List //单链表类
int Student_Count; //学生人数
Node *Head_Point; //头节点,不存储学生信息
public:
static bool Is_Previous; //在查询,删除或者修改等操作中,我们需要得到一个指向我们想要操作的节点的指针,如果是查询或者修改,我们需要指向当前学生;如果是删除,我们就需要指向被删除学生的前一个学生。
Linked_List()
Node *p = new Node; //当我们新建一个单链表对象的时候,我们应该为它创建一个头节点,并完成该类的成员初始化工作。
this->Head_Point =p;
Head_Point->Next_Student= NULL;
Student_Count = 0;
~Linked_List() //析构函数
Linked_List(const Linked_List &list); //拷贝构造函数
Linked_List& operator=(const Linked_List &list); //赋值构造函数
void Clear_Linked_List(); //销毁链表
void Print_Student_Details(string name); //利用学生姓名打印学生信息
void Print_Student_Details(int studeng_id); //利用学生学号打印学生信息
Node* Find_Name(string name); //利用学生姓名找到学生,并返回指向该学生的指针
Node* Find_Student_Id(int studeng_id); //利用学生学号找到学生,并返回指向该学生的指针
void Edit_Student(); //该函数可以修改学生信息,通过查找到学生姓名来进行修改
void Student_Id_Sort();//学号大小来排序,使用冒泡排序法
void Student_Name_Sort(); //对每一个名字的姓进行排序
void Delete_Student(); //删除学生信息,利用姓名查找并删除
void Print_Every_Student(); //打印所有学生的信息
//这两个保存和读取的函数并没有添加到菜单栏中,这两个函数是在我写好这个类之后过了好久才写的,也懒得去改动菜单栏了,但是我测试过是可行的。
void Write_Every_Student_TXT() //保存所有学生信息到文件中
ofstream fout("H:\\\\Visual Studio 2015\\\\My projects\\\\Linked_List\\\\Linked_List\\\\Student.txt");
//保存到该文件目录下的文件,如果没有该文件,将会创建该文件,有的话,会清空原有文件中的所有内容
Node *p = Head_Point;
if (!fout.is_open()) //如果文件创建失败,就返回不进行后续操作
cout << "文件创建失败!!!";
return;
fout << "姓名" << " 学号" << " 性别" << " 年龄" << " 班级" << " 健康状况" << endl;
for (int i = 1; i <= Student_Count; i++)
//利用左对齐,填充字符控制格式化的输出到文件
p = p->Next_Student;
fout << left << setw(15) << setfill(' ') << p->Name;
fout << left << setw(12) << setfill(' ') << p->Student_ID;
fout << left << setw(8) << setfill(' ') << p->Gender;
fout << left << setw(10) << setfill(' ') << p->Age;
fout << left << setw(14) << setfill(' ') << p->Class;
fout << left << setw(18) << setfill(' ') << p->Health_Status << endl;
fout.close(); //关闭该文件流
void Read_Every_Student_TXT() //从文件中读取学生信息
ifstream fin("H:\\\\Visual Studio 2015\\\\My projects\\\\Linked_List\\\\Linked_List\\\\Student.txt");
if (!fin.is_open())
cout << "文件打开失败!!!";
return;
Node *p = Head_Point;
char status[80]; //文件中的第一行默认显示一些信息,所以这一行信息应该被读取掉然后丢弃
fin.getline(status,100); //读取100个字符到getline中
string Name;
int Student_ID;
string Gender;
int Age;
string Class;
string Health_Status;
while (fin.good()) //good()可以获取是否处于一种好的状态,达到文件尾部或者类型不匹配都会返回false
//将文件中的信息添加到链表中
fin >> Name >> Student_ID >> Gender >> Age >> Class >> Health_Status;
this->Add_Student(Name ,Student_ID ,Gender ,Age , Class ,Health_Status);
fin.close(); //关闭文件流
void Add_Student(string name); //添加学生,利用节点的构造函数添加一个学生
void Add_Student(string name, int student_id, string gender, int age, string Class, string health_status);
//输入所有信息直接创建
int Show_Print_Menu(); //显示打印菜单
int Show_Edit_Menu(); //显示编辑菜单
int Show_Query_Menu(); //显示查询菜单
int Show_Main_Menu(); //显示主菜单
;
#endif
⒉Linked_List.cpp
#include "stdafx.h"
#include"Linked_List.h"
bool Linked_List::Is_Previous = true; //默认取指向前一个学生的指针
void Linked_List::Clear_Linked_List()
Node *p, *q;
p = this->Head_Point;
for (int i = 1; i <= this->Student_Count; i++)
//从头节点开始销毁,每次保存销毁节点的后一个节点,以便销毁其后的节点
q = p;
p = p->Next_Student;
delete q;
delete p; //创建的节点数目应该是头节点数加上学生数,所以这里最后还需要销毁最后一个学生信息
this->Student_Count = 0;
Linked_List::Linked_List(const Linked_List &list)
//实现两个链表的深拷贝
Node *q = list.Head_Point;
Linked_List *p = new Linked_List; //创建一个新的链表
Node *k = new Node;
for (int i = 1; i <= list.Student_Count; i++)
q = q->Next_Student;
p->Add_Student(q->Name, q->Student_ID, q->Gender, q->Age, q->Class, q->Health_Status);
void Linked_List::Print_Student_Details(string name)
Node *p = Find_Name(name);
if (p->Name != "NULL")
cout << "姓名" << " 学号" << " 性别" << " 年龄" << " 班级" << " 健康状况" << endl;
cout << left << setw(15) << setfill(' ') << p->Name;
cout << left << setw(12) << setfill(' ') << p->Student_ID;
cout << left << setw(8) << setfill(' ') << p->Gender;
cout << left << setw(10) << setfill(' ') << p->Age;
cout << left << setw(14) << setfill(' ') << p->Class;
cout << left << setw(18) << setfill(' ') << p->Health_Status << endl;
void Linked_List::Print_Student_Details(int studeng_id)
Node *p = Find_Student_Id(studeng_id);
if (p->Name != "NULL")
cout << "姓名" << " 学号" << " 性别" << " 年龄" << " 班级" << " 健康状况" << endl;
cout << left << setw(15) << setfill(' ') << p->Name;
cout << left << setw(12) << setfill(' ') << p->Student_ID;
cout << left << setw(8) << setfill(' ') << p->Gender;
cout << left << setw(10) << setfill(' ') << p->Age;
cout << left << setw(14) << setfill(' ') << p->Class;
cout << left << setw(18) << setfill(' ') << p->Health_Status << endl;
void Linked_List::Print_Every_Student()
Node *p;
p = Head_Point;
cout << "姓名" << " 学号" << " 性别" << " 年龄" << " 班级" << " 健康状况" << endl;
for (int i = 1; i <= Student_Count; i++)
p = p->Next_Student;
cout << left << setw(15) << setfill(' ') << p->Name;
cout << left << setw(12) << setfill(' ') << p->Student_ID;
cout << left << setw(8) << setfill(' ') << p->Gender;
cout << left << setw(10) << setfill(' ') << p->Age;
cout << left << setw(14) << setfill(' ') << p->Class;
cout << left << setw(18) << setfill(' ') << p->Health_Status << endl;
void Linked_List::Add_Student(string name)
Node *p = Head_Point;
Node *q = new Node(name);
Student_Count++;
if (Student_Count == 1)
Head_Point->Next_Student = q;
else
for (int i = 1; i < Student_Count; i++)
p = p->Next_Student;
p->Next_Student = q;
return;
void Linked_List::Add_Student(string name, int student_id, string gender, int age, string Class, string health_status)
Node *p = Head_Point;
Node *q = new Node(name, student_id, gender, age, Class, health_status);
//创建一个节点并将它与链表连接
Student_Count++;
for (int i = 1; i < Student_Count; i++)
p = p->Next_Student;
p->Next_Student = q;
return;
int Linked_List::Show_Print_Menu()
for (; 1;) //进行一些操作之后便于快速跳出该菜单
system("cls");
cout << " ┎┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┒" << endl;
cout << " ┋ 学生教务管理系统 ┋" << endl;
cout << " ┋ ①姓名排序 ②学号排序 ┋" << endl;
cout << " ┋ ③添加顺序 ④返回菜单 ┋" << endl;
cout << " ┋ ┋" << endl;
cout << " ┖┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┚" << endl;
cout << "请输入相应操作前面的序号:";
int Operation_Number;
cin >> Operation_Number;
if (Operation_Number == 4)
system("cls"); //清空控制台的显示
break;
if (Operation_Number == 3)
Print_Every_Student();
system("pause"); //显示打印结果,等待我们按任意键再进入到菜单选项
if (Operation_Number == 2)
Linked_List Id_Sort;
Id_Sort = *this; //调用赋值构造函数
Id_Sort.Student_Id_Sort();
Id_Sort.Print_Every_Student();
Id_Sort.Clear_Linked_List(); //打印完成之后销毁排好序的链表
system("pause");
if (Operation_Number == 1)
Linked_List Name_Sort;
Name_Sort = *this;
Name_Sort.Student_Name_Sort();
Name_Sort.Print_Every_Student();
Name_Sort.Clear_Linked_List();
system("pause");
return 0;
int Linked_List::Show_Main_Menu() //子菜单的跳转
for (; 1;)
cout C项目 文件,结构体,链表,排序, 学生信息管理系统
《程序设计基础》实验题目2 c文件读取(反序列化?) 链表排序