#include<iostream>
#include<fstream>
#include<cstdlib>
using namespace std;
/*
* 信息包括学号、姓名、专业、四门课成绩、总分、名次;
*/
struct Student {
string name;
int number=1000;//学号
string major;//专业
double score[4];//四门课的成绩
double sumscore=-1;//总分
int rank=-1;//名次
Student* next=nullptr;
};
void exchange(Student* p, Student* q);//俩节点仅交换属性值
void getTxt();
void student_information(Student* student);
/*
系统可对学生信息浏览、增加、删除和修改;
按学生成绩确定名次及信息输出,双向冒泡排序、希尔排序、快速排序、堆排序。
要求可对学生信息查询,根据学号或姓名进行查找;
信息修改仅可修改四门课成绩;
文件存取学生信息。
* 考虑用链表来存储、访问数据
* 考虑头插法进行链表的增长
*/
class Basement {
Student* first ;//头指针
public:
Basement();//构造函数
void Load();//将文本中的信息加载进来
void Save();//将信息保存到文本文件中
void View();//从链表头部开始查看学生信息
void Input();//添加某一学生信息
void Delete();//删除某一学生
void Modify();//修改某一学生的四门成绩
void Sort();//进行学生排名(选择排序法)
void BubbleSort();//冒泡排序法
void ShellSort();//希尔排序法
void QuickSort();//快速排序
void HeapSort();//堆排序
void Enquire();//某一具体学生信息查询
void Rand_Creat(int n);//随机生成n个学生在链表里面
Student *findByName(string name);//通过学生名字确定该学生
Student *findByNumber(int number);//通过学号确定该学生
bool Number_Judge(int number);//学号查重
//~Basement();//析构函数,防止内存泄漏
};
/*
* 冒泡排序法
*/
void Basement::BubbleSort() {
Student* p = first;
}
/*
* 堆排序
*/
void Basement::HeapSort() {
}
/*
* 快速排序
*/
void Basement::QuickSort() {
}
/*
* 希尔排序
*/
void Basement::ShellSort() {
}
/*
* 析构函数,防止内存泄漏
*/
/*
Basement::~Basement() {
Student* p = first;
Student* q = p->next;
while (q) {
delete p;
p =q;
q = q->next;
}
delete p;
}
*/
/*
* 随机生成n个学生在链表里面
*/
void Basement::Rand_Creat(int n) {
int i = 0;
while (i < n) {
Student* student = new Student;
student->major = "随机生成";
student->name = "随机生成";
int number=1000;
while (!Number_Judge(number)) {
number++;
}
student->number = number;
student->score[1] = rand() % 40 + 60;
student->score[2] = rand() % 40 + 60;
student->score[3] = rand() % 40 + 60;
student->score[0] = rand() % 40 + 60;
student->sumscore = student->score[0] + student->score[1] + student->score[2] + student->score[3];
student->next = first->next;
first->next = student;
i++;
}
}
/*
* 学号查询是否重合
*/
bool Basement::Number_Judge(int number) {
Student *p = first->next;
while (p) {
if (p->number == number)
return false;
p = p->next;
}
return true;
}
/*
* 将文本文件的信息加载进来
*/
void Basement::Load() {
cout << "是否需要随机生成学生信息(1.是(按其它任意键不生成))" << endl;
string choose;
cin >> choose;
if (choose == "1") {
cout << "请输入需要生成多少随机学生" << endl;
int n;
cin >> n;
Rand_Creat(n);
}
}
/*
* 将信息保存到文本文件中
*/
void Basement::Save() {
std::ofstream outFile;//打开文件
outFile.open("D:\\Test.txt");
Student* p = first->next;
while (p) {//写入数据
outFile << p->major << '\t' << p->name << '\t' << p->number << '\t' << p->score[0] << '\t' << p->score[1] << '\t' << p->score[2] << '\t' << p->score[3] << '\t' << p->sumscore << endl;
p = p->next;
}
cout << "数据保存成功!" << endl;
}
/*
* 添加某一学生信息
*/
void Basement::Input() {
Student* new_student;
new_student = new Student;
new_student->next = nullptr;
cout << "请输入新学生姓名" << endl;
cin >> new_student->name;
cout << "请输入新学生学号" << endl;
a: {
cin >> new_student->number;
if (!Number_Judge(new_student->number)) {
cout << "学号重复,请重新输入!"<<endl;
goto a;
}
}
cout << "请输入新的学生专业" << endl;
cin >> new_student->major;
cout << "请输入新的学生四门课的成绩" << endl;
cin >> new_student->score[0] >> new_student->score[1] >> new_student->score[2] >> new_student->score[3];
new_student->sumscore = new_student->score[0] + new_student->score[1] + new_student->score[2] + new_student->score[3];
new_student->next = first->next;
first->next = new_student;
cout << "添加成功!是否要继续添加学生:1.继续(按其它任意键退出该功能)" << endl;
string choose;
cin >> choose;
if (choose == "1")
Input();
else cout << "已成功退出该功能!";
}
/*
* 构造函数
* 头指针悬空
*/
Basement::Basement() {
first = new Student;
first->next =NULL;
first->major = "";
first->name = "";
first->number = -1;
}
/*
* 从链表头开始查询学生信息
*/
void Basement::View() {
cout <<"学生学号"<< '\t';
cout <<"学生姓名"<< '\t';
cout <<"学生专业" << '\t';
cout << "课程一" << '\t';
cout << "课程二" << '\t';
cout << "课程三" << '\t';
cout << "课程四" << '\t';
cout << "总 分" << '\t';
cout << "排 名" << '\t';
cout << endl;
Student* p = first->next;
while (p) {
student_information(p);
p = p->next;
}
}
/*
* 通过学号确定该学生
*/
Student* Basement::findByNumber(int number){
Student* p = first->next;
while (p!=NULL)
{
if (p->number == number)return p;//此时p为number所对应的学生地址
else p = p->next;
}
return p;//此时p为null
}
/*
* 通过姓名确定该学生
*/
Student *Basement::findByName(string name) {
Student* p = first->next;
do {
if (p->name == name)return p;//此时p为name对应的学生地址
else p = p->next;
} while (p);
return p;//此时p为null
}
/*
* 某一学生的所有信息展示
*/
void student_information(Student *student) {
cout << student->number << '\t';
cout << student->name << '\t';
cout << student->major << '\t';
cout << student->score[0] << '\t';
cout << student->score[1] << '\t';
cout << student->score[2] << '\t';
cout << student->score[3] << '\t';
cout << student->sumscore << '\t';
cout << student->rank << '\t';
cout << endl;
}
/*
* 修改学生的成绩
*/
void Basement::Modify() {
cout << "请输入要修改的学生的学号:" << endl;
int number;
cin >> number;
Student * p= findByNumber(number);
if (p != nullptr) {
cout << "请输入新的四门课成绩:" << endl;
cin >> p->score[0] >> p->score[1] >> p->score[2] >> p->score[3];
p->sumscore = p->score[0] + p->score[1] + p->score[2] + p->score[3];
cout << "修改成功!"<<endl;
}
else {
cout << "没有该学号,请选择(1)重新输入或按 随机键 退出该功能"<<endl;
string choose;
cin >> choose;
if (choose == "1") {
Modify();
}
else {
cout << "您已成功退出修改学生成绩的功能"<<endl;
}
}
}
/*
* 删除某一学生的信息
*/
void Basement::Delete() {
cout << "请输入需要删除的学生的学号:" << endl;
int number;
cin >> number;
Student * p = findByNumber(number);
if(p!=NULL){//在链表里面找到了该学生
Student* q = first;
while(q->next!=p){
q = q->next;
}
q->next = p->next;
delete p;//到此删除节点成功
cout << "删除成功!自动退出该功能。" << endl;
}
else {
cout << "没有找到该学生的信息,自动退出该功能。" << endl;
}
}
/*
* 主菜单
* 登录系统后将磁盘文件中保存的学生成绩信息读取到内存中
* 保存学生成绩档案信息到文本文件
* 构造函数需要包含磁盘文件内容
*/
void menu(Basement base) {
cout << "*****************"<<endl;
cout << "*1.浏览学生信息 *" << endl;//按成绩排名+学生信息查询(按学号+按姓名)
cout << "*2.学生信息修改 *" << endl;
cout << "*3.新增学生信息 *" << endl;
cout << "*4.删除学生信息 * " << endl;
cout << "*5.查看具体学生 * " << endl;
cout << "*6.进行学生排名 * " << endl;
cout << "*0.退出该系统 *" << endl;
cout << "*请选择: *"<<endl;
cout << "*****************" << endl;
char choose;
cin >> choose;//人进行选择(只能输入一个字符,否则可能退出系统)
switch (choose)
{
case '0':cout << "已经成功退出了该系统" << endl;
break;
case '1'://浏览学生信息
base.View();
menu(base);
break;
case '2'://学生信息修改
base.Modify();
menu(base);
break;
case '3'://新增学生信息
base.Input();
menu(base);
break;
case '4'://删除学生信息
base.Delete();
menu(base);
break;
case '5'://某一具体学生信息查询
base.Enquire();
menu(base);
break;
case '6'://进行学生排名
base.Sort();
menu(base);
break;
default:
cout << "输入非法,请重新选择"<<endl;
menu(base);
break;
}
}
int main() {
//getTxt();
Basement base;
base.Load();//把文本文件中的信息导入到数据结构里面
menu(base);//主菜单
cout << "是否保存操作结果?\t是(1)\t否(除‘1’以外任意键)" << endl;
char choice;
cin >> choice;
if (choice == '1') {
base.Save();//此处暂时未解决
cout << "保存成功!"<< endl;
}
else {
cout << "成功退出系统!" << endl;
}
}
/*
* 初始化一个文本文件
* 该文件可以用来没有数据时使用
* 本程序可用也可不用
*/
void getTxt() {
char fileName[30], name[30];
string major;
int number;
double score[4];
//double sumscore;
ofstream outstuf;//建立输出文件流对象
cout << "Please input the name of students file:\n";
cin >> fileName;//输入文件名
outstuf.open(fileName, ios::out);//连接文件,指定打开方式
if (!outstuf)//调入重载算符函数测试流
{
cerr << "File could not be open." << endl;
abort();
}
outstuf << "This is a file of students\n";//写入一行标题
cout << "Input the number,name,majior,and score[4]:"
<< "(Enter Ctrl+Z to end Input)\n?";
while (cin >> number >> name >> major >> score[0] >> score[1]>>score[2]>>score[3]) {
outstuf << number << '\t' << name << '\t' <<major << '\t' << score[0] << '\t' << score[1] << '\t' << score[2] << '\t' << score[3] << '\t' << (score[0]+score[1]+score[2]+score[3]) << '\n';//向流插入数据
cout << "?";
}
outstuf.close();
}
/*
* 以app方式打开文件,向文件中追加数据
* 一个文本文件一旦建立之后,不能随意插入数据,但可以在文件尾部追加数据
*/
int Append(char* fileName)
{
char name[30], ch;
int number, score;
ofstream outstuf(fileName, ios::app);//以追加方式打开文件
if (!outstuf)
{
cerr << "File could not be open." << endl;
return 0;//返回0表示文件不能打开
}
cout << "DO you want append record to " << fileName << "?(Y or N)\n";
cin >> ch;//用户应答
while (ch == 'Y' || ch == 'y')
{
cout << "Input the number, name, and score :\n";
cin >> number >> name >> score;
outstuf << number << '\t' << name << '\t' << score << '\n';//追加一个记录
cout << "?(Y or N)";
cin >> ch;//用户问答
if (ch == 'N' || ch == 'n')
cout << "Close file.\n";
}
outstuf.close();
return 1;//返回1表示文件正常操作
}
/*
* 某一具体学生信息查询
*/
void Basement::Enquire() {
cout << "请选择查询方式:\t1.输入姓名查询\t2输入学号查询" <<endl;
char choose;
cin >> choose;
if (choose == '1') {
cout << "请输入学生的姓名:"<<endl;
string name;
cin >> name;
if (findByName(name)) {
cout << "该学生的信息为:"<<endl;
student_information(findByName(name));
}
else {
cout << "查无此人"<<endl;
}
}else if(choose=='2'){
cout << "输入学生的学号:" << endl;
int number;
cin >> number;
if (findByNumber(number)) {
cout << "该学生的信息为:" << endl;
student_information(findByNumber(number));
}
else {
cout << "查无此人"<<endl;
}
}
else {
cout << "输入非法,已成功退出"<<endl;
}
}
/*
* 选择排序法
* 根据总分对学生的成绩进行排名
*/
void Basement::Sort() {
Student* p = first;
Student* q = first;
while (p->next) {
p = p->next;
q = p;
Student *s = q;
while (q->next) {
q = q->next;
if (s->sumscore < q->sumscore)
s = q;//s记录剩下节点中sumscore属性值最大的节点
}
exchange(s, p);//s和q互换各个属性值
}
p = first->next;
int rank = 1;
while (p) {
p->rank = rank;
rank++;
p = p->next;
}
cout << "排序成功!"<<endl;
}
/*
* 俩节点仅互换值,不改指针
*/
void exchange(Student* p, Student* q) {
Student* s = new Student;
s->major=p->major;
s->name=p->name;
s->number=p->number;
s->score[1] =p->score[1] ;
s->score[2] = p->score[2];
s->score[3] = p->score[3];
s->score[0] = p->score[0];
s->sumscore = p->sumscore;
p->major = q->major;
p->name = q->name;
p->number = q->number;
p->score[0] = q->score[0];
p->score[1] = q->score[1];
p->score[2] = q->score[2];
p->score[3] = q->score[3];
p->sumscore = q->sumscore;
q->major = s->major;
q->name = s->name;
q->number = s->number;
q->score[0] = s->score[0];
q->score[1] = s->score[1];
q->score[2] = s->score[2];
q->score[3] = s->score[3];
q->sumscore = s->sumscore;
delete s;
}
学生档案管理系统(c++)代码实现
最新推荐文章于 2024-07-22 18:08:40 发布