尝试重新设计与编写大一第一学期的 c++课设——学生信息管理系统。本文作简单思路分析与代码分享。B 站视频内录制了从头开始写的整个过程:课程设计|c++控制台简易学生信息管理系统
思路
要求:能够录入,显示,查找,删除,文件存取学生信息
以当时的知识是以链表来实现的,这次也是使用链表。
首先,创建一个链表结点类用于存放学生的信息,每个对象都是一个学生。
其次,创建一个链表类用于将结点连接起来。
最后,利用链表类已经创建好的各种接口,在 main 函数中进行装配,实现所需要的各种功能。
链表结点类
- 类名:CStudent
- 属性:姓名、性别、成绩、其余本质相同的属性(如班级号,学号)省略。
- 方法:以不同方式显示该学生所有信息、手动录入学生信息
类声明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #pragma once
class CStudent { char name[20]; bool sex; int score; public: CStudent* next;
public: CStudent(const char p_name[], bool p_sex, int p_score); CStudent(); void input(); void show(int method); char* getName() { return name; } bool getSex() { return sex; } int getScore() { return score; } ~CStudent(); };
|
类实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| #include "CStudent.h" #include <cstring> #include <iostream> using namespace std; CStudent::CStudent(const char p_name[], bool p_sex, int p_score) { strcpy(name, p_name); sex = p_sex; score = p_score; } CStudent::CStudent() { input(); } void CStudent::input() { cout << "请输入学生姓名:" << endl; cin >> name; cout << "请输入学生性别(1为男,0为女):" << endl; int isex; cin >> isex; sex = isex ? true : false;
cout << "请输入学生成绩:" << endl; cin >> score;
}
void CStudent::show(int method) {
switch (method) { case 0: cout << name<<"\t" << (sex ? "男" : "女")<<"\t" << score<<"\t" << endl;
break; case 1: cout << "姓名:" << name << endl << "性别:" << (sex ? "男" : "女") << endl << "成绩:" << score << endl << endl; break; default: break; }
}
CStudent::~CStudent() { }
|
链表类
类声明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #pragma once #include "CStudent.h"
class CStudentList { CStudent* head; public: CStudentList(int n); CStudentList(CStudent s[],int n); CStudentList(const char fileName[]); CStudentList(); void showList(); int search(const char name[]); void deleteNode(CStudent*p); int deleteByName(const char name[]); void save(const char fileName[]); void open(const char fileName[]); ~CStudentList(); };
|
类实现
构造函数
我设计了四个构造函数。
1.如果没有参数,那么就只建立一个空链表,即只有一个头结点的链表。
1 2 3 4 5 6 7
|
CStudentList::CStudentList() { head = new CStudent("HEAD", 1, 100); head->next = NULL; }
|
2.手动录入信息的构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
CStudentList::CStudentList(int n) { head = new CStudent("HEAD",1,100); head->next = NULL; for (int i = 0; i < n; i++) { CStudent *newNode = new CStudent(); newNode->next = head->next; head->next = newNode; } }
|
3.通过数组自动录入信息的构造函数
和上一个差不多。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
CStudentList::CStudentList(CStudent s[], int n) { head = new CStudent("HEAD", 1, 100); head->next = NULL; for (int i = 0; i < n; i++) { CStudent *newNode = new CStudent(s[i].getName(),s[i].getSex(),s[i].getScore()); newNode->next = head->next; head->next = newNode; } }
|
4.通过文件自动录入信息的构造函数
使用到了另一个成员函数open()
1 2 3 4 5 6 7 8 9
|
CStudentList::CStudentList(const char fileName[]) { head = new CStudent("HEAD", 1, 100); head->next = NULL; open(fileName); }
|
显示链表
1 2 3 4 5 6 7 8 9 10 11 12
|
void CStudentList::showList() { CStudent*p = head->next; cout << "姓名\t性别\t成绩" << endl; while (p != NULL) { p->show(0); p = p->next; } }
|
查询结点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
int CStudentList::search(const char name[]) { int num = 0; CStudent*p = head->next; cout << "---------查找结果---------" << endl; while (p != NULL) { if (strcmp(p->getName(),name)==0) { num++; p->show(0); } p = p->next; } return num; }
|
查找删除
由于删除结点与查找要删除的结点相对独立,因此将删除结点独立出来一个函数,以便查找删除不同属性的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
void CStudentList::deleteNode(CStudent*p) { CStudent*p1 = head, *p2 = head->next; while (p2 != p) { p1 = p1->next; p2 = p2->next; } p1->next = p->next; delete p; }
|
以查找姓名的删除函数为例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
int CStudentList::deleteByName(const char name[]) { CStudent*p = head->next; while (p != NULL) { if (strcmp(p->getName(), name) == 0) { deleteNode(p); return 0; } p = p->next; } return -1; }
|
读取数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
void CStudentList::open(const char fileName[]) { CStudent* p = head->next; while (p != NULL) { delete head; head = p; p = p->next; } ifstream fin(fileName); while (!fin.eof()) { char name[20]; bool sex=0; int score=0;
fin >> name >> sex >> score;
CStudent *newNode = new CStudent(name,sex,score); newNode->next = head->next; head->next = newNode; } }
|
保存数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
void CStudentList::save(const char fileName[]) { ofstream fout(fileName); CStudent *p = head->next; while (p != NULL) { fout << p->getName() << " " << p->getSex() << " " << p->getScore() <<endl; p = p->next; } }
|
析构函数
1 2 3 4 5 6 7 8 9 10 11
| CStudentList::~CStudentList() { CStudent* p = head->next; while (p != NULL) { delete head; head = p; p = p->next; } delete head; }
|
菜单
菜单比较简单,整个程序主要流程:
- 显示菜单选项,等待输入选项编号
- 分支语句,按照不同选项调用链表提供的函数
- 如果没有选择退出选项就循环
菜单函数示例
1 2 3 4 5 6 7 8 9
| void menu() { cout << "========学生信息管理系统========" << endl; cout << "1.显示学生信息表" << endl; cout << "2.查找学生信息" << endl; cout << "3.从文件读取" << endl; cout << "4.将数据存入文件" << endl; cout << "0.退出" << endl; }
|
选项分支示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| int main() {
int opt = -1; CStudentList list("data.txt"); while (opt != 0) { menu(); cin >> opt; switch (opt) { case 1: system("cls"); list.showList(); break; default: break; }
} return 0; }
|