|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 MUYIXUE 于 2024-7-6 15:15 编辑
非科班出生的小白一枚. 今天学习fishcC++入门课程的时候,看到"复杂的数据类型05_对象的基础:结构.mp4",然后就突发奇想,想要试一下二级菜单,没想到文思泉涌!!!写完后我自己都懵逼了!!!感觉写的有点不错,特来分享!!
目前写完命令行界面,还没有写好功能.现在发现了一些地方设计的不是很好,后面写完也会重构. ------现在已经写到了数据的保存了,更新一下代码.
浅浅的谈一下感想: 写的真的累,难受的是刚开始写的时候没有梳理好思路,现在依靠标志的管理,界面功能切换没有问题,然而功能却写的一塌糊涂,很多代码重复出现,
教训:
1. 对于链表的使用,真的要有一个迭代器,如果每一个细节都需要多次考虑分析,会带来很大的工作量.
2. 二级展开菜单的代码做的不好,其中涉及到的很多常量不可以自动更新,所以添加或者修改功能会带来繁重的工作量.
3. 一定要多敲代码,我没有学习过数据结构,但是我之前在书上看到过链表的原理,所以我就自己摸索自己实现了一个双向链表,虽然有些部分很多余,但是很离谱的是:即使刚开始我写起来很慢,但当我反复书写6-7次链表后,我竟然越写越快!!,我对于这个原来很陌生的结构慢慢熟悉,最后写着就知道内存中发生了什么,出错了应该如何检查,都自然浮现于眼前.
如果说什么是屎山,估计我这个就是,因为有很多重复的功能没有封装,这个程序明显分为3个部分,1. 链表管理,2. 用户界面 3. 文件管理(还没有写).但是接近800行的代码,不是十分重要的代码,整理起来过于耗费心神,所以我也不打算整理了,后面C++入门课程学习完后,一定要在写代码前就理清所有的思路.#include <iostream>
#include <fstream>
#include <format>
#define GUI_WIDTH "40"
using namespace std;
enum gender
{
boy, girl
};
struct student {
string name = "";
long IDcard = 0;
gender sex = boy;
};
struct data {
struct student* data;
struct data* pre;
struct data* post;
};
const char* menu[] = {
"学生管理系统",
//主菜单选项
"1. 创建表单",
"2. 打开表单",
"3. 添加学生",
"4. 查询学生",
"5. 删除学生",
"6. 打印表单",
"7. 保存表单",
"q. 退出系统",
//查询学生菜单
"1. 名字查询", //9
"2. 身份证查询",
//删除学生菜单
"1. 请输入名字", //11
"2. 请输入身份证",
//打印表单菜单
"1. 打印到文件", //13
"2. 打印到控制台",
//二级菜单退出
"退出二级菜单"
};
const char* message[]{
"请输入数字选项: ",
"请输入合法值 !",
"请输入二级菜单数字选项!"
};
//用来标记菜单的界限
enum menu_edge {
main_menu = 8,
search_menu = main_menu + 2,
delete_menu = search_menu + 2,
print_menu = delete_menu + 2
};
static void flush_screen(string* menu, string* message) {
system("cls");
cout << format("{0:#^" GUI_WIDTH "s}", menu[0]) << endl;
for (int i = 1; i <= main_menu; i++) {
cout << format("{0: <" GUI_WIDTH "s}", menu[i]) << endl;
}
cout << format("{0: <" GUI_WIDTH "s}", *message);
}
bool change_menu_option(bool secondary_menu_flag, int menu_option_num, string* menu_dynamic, string* message_dynamic) {
bool status = true;
if (secondary_menu_flag) {
switch (menu_option_num) {
case 4://查询
menu_dynamic[menu_option_num] += "->";
menu_dynamic[menu_option_num] += menu[menu_option_num + 5];
menu_dynamic[menu_option_num + 1] += " ";
menu_dynamic[menu_option_num + 1] += menu[menu_option_num + 6];
menu_dynamic[menu_option_num + 2] += " ";
menu_dynamic[menu_option_num + 2] += "q. ";
menu_dynamic[menu_option_num + 2] += menu[15];
*message_dynamic = message[2];
break;
case 5://删除';
menu_dynamic[menu_option_num] += "->";
menu_dynamic[menu_option_num] += menu[menu_option_num + 6];
menu_dynamic[menu_option_num + 1] += " ";
menu_dynamic[menu_option_num + 1] += menu[menu_option_num + 7];
menu_dynamic[menu_option_num + 2] += " ";
menu_dynamic[menu_option_num + 2] += "q. ";
menu_dynamic[menu_option_num + 2] += menu[15];
*message_dynamic = message[2];
break;
case 6://打印
menu_dynamic[menu_option_num] += "->";
menu_dynamic[menu_option_num] += menu[menu_option_num + 7];
menu_dynamic[menu_option_num + 1] += " ";
menu_dynamic[menu_option_num + 1] += menu[menu_option_num + 8];
menu_dynamic[menu_option_num + 2] += " ";
menu_dynamic[menu_option_num + 2] += "q. ";
menu_dynamic[menu_option_num + 2] += menu[15];
*message_dynamic = message[2];
break;
default:
status = false;
break;
}
}
else {
int option_num = sizeof(menu) / sizeof(char*);
for (int i = 0; i < option_num; i++) {
menu_dynamic[i] = menu[i];
}
*message_dynamic = message[0];
}
return status;
}
struct data* make_list() {//makelist不需要申请任何内存,只需要返回一个表头即可
struct data* first = NULL;
first = new struct data;
first->data = NULL;
first->pre = NULL;
first->post = NULL;
return first;
}
struct data* add_student(struct data* list, string name, long IDcard, gender sex) {
if (list != NULL) {
struct data* temp = new struct data; //首先创建节点
temp->data = new struct student; //然后创建数据
temp->data->IDcard = IDcard;
temp->data->name = name;
temp->data->sex = sex; //然后初始化数据
struct data* ptr = list->post; //默认向后增加数据
list->post = temp;
temp->pre = list;
temp->post = ptr;
return temp;
}
else {
cerr << "你还没有创建列表,无法添加学生!" << endl;
system("pause");
}
}
struct data* search_student(struct data* list, string name) {
struct data* temp_ptr = NULL;
string temp_name = name;
if (list == NULL) {//如果是使用make_list创建表头,不可能为空
cerr << "空指针无法索引任何数据 !" << endl;
exit(EXIT_FAILURE);
}
else {
if (list->pre == NULL && list->post == NULL) {
cout << "你还没有添加任何学生!" << endl;
}
else if (list->pre == NULL && list->post != NULL) {//这是表头
struct data* temp = list;
for (;;) {
temp = temp->post;
if (temp->data->name == temp_name) {
cout << "名字: " << temp->data->name << endl;
cout << "身份证号: " << temp->data->IDcard << endl;
if (temp->data->sex == boy) {
cout << "性别: " << "男" << endl;
}
else if (temp->data->sex == girl) {
cout << "性别: " << "女" << endl;
}
temp_ptr = temp;
break;
}
if (temp->post == NULL) {//如果下一个列表后就没有链表就表示结束
cout << "你创建的表中不含有这个学生" << endl;
break;
}
}
}
else if (list->pre != NULL && list->post == NULL) {//这是表尾
struct data* temp = list;
for (;;) {
if (temp->data == NULL) {
cout << "你创建的表中不含有这个学生" << endl;
break;
}
if (temp->pre == NULL) {//如果下一个列表后就没有链表就表示结束
cout << "你创建的表中不含有这个学生" << endl;
break;
}
if (temp->data->name == temp_name) {
cout << "名字: " << temp->data->name << endl;
cout << "身份证号: " << temp->data->IDcard << endl;
if (temp->data->sex == boy) {
cout << "性别: " << "男" << endl;
}
else if (temp->data->sex == girl) {
cout << "性别: " << "女" << endl;
}
temp_ptr = temp;
break;
}
temp = temp->pre;
}
}
else {//这是表的中间一个节点
bool not_find_pre = false;
bool not_find_post = false;
bool not_find_curr = false;
//自己检查自己
struct data* temp = list;
if (temp->data->name == temp_name) {
cout << "名字: " << temp->data->name << endl;
cout << "身份证号: " << temp->data->IDcard << endl;
if (temp->data->sex == boy) {
cout << "性别: " << "男" << endl;
}
else if (temp->data->sex == girl) {
cout << "性别: " << "女" << endl;
}
temp_ptr = temp;
}
else {
not_find_curr = true;
}
//向前检索
temp = list;
for (;;) {
temp = temp->pre;
if (temp->data->name == temp_name) {
cout << "名字: " << temp->data->name << endl;
cout << "身份证号: " << temp->data->IDcard << endl;
if (temp->data->sex == boy) {
cout << "性别: " << "男" << endl;
}
else if (temp->data->sex == girl) {
cout << "性别: " << "女" << endl;
}
temp_ptr = temp;
break;
}
if (temp->pre == NULL) {//如果下一个列表后就没有链表就表示结束
not_find_pre = true;
break;
}
}
//向后检索
temp = list;
for (;;) {
temp = temp->post;
if (temp->data->name == temp_name) {
cout << "名字: " << temp->data->name << endl;
cout << "身份证号: " << temp->data->IDcard << endl;
if (temp->data->sex == boy) {
cout << "性别: " << "男" << endl;
}
else if (temp->data->sex == girl) {
cout << "性别: " << "女" << endl;
}
temp_ptr = temp;
break;
}
if (temp->data == NULL) {
cout << "你创建的表中不含有这个学生" << endl;
break;
}
if (temp->post == NULL) {//如果下一个列表后就没有链表就表示结束
not_find_post = true;
break;
}
}
if (not_find_curr && not_find_pre && not_find_post) {
cout << "你创建的表中不含有这个学生" << endl;
}
}
}
return temp_ptr;
}
struct data* search_student(struct data* list, long IDcard) {
struct data* temp_ptr = NULL;
long temp_IDcard = IDcard;
if (list == NULL) {//如果是使用make_list创建表头,不可能为空
cerr << "空指针无法索引任何数据 !" << endl;
exit(EXIT_FAILURE);
}
else {
if (list->pre == NULL && list->post == NULL) {
cout << "你还没有添加任何学生!" << endl;
}
else if (list->pre == NULL && list->post != NULL) {//这是表头
struct data* temp = list;
for (;;) {
temp = temp->post;
if (temp->data->IDcard == temp_IDcard) {
cout << "名字: " << temp->data->name << endl;
cout << "身份证号: " << temp->data->IDcard << endl;
if (temp->data->sex == boy) {
cout << "性别: " << "男" << endl;
}
else if (temp->data->sex == girl) {
cout << "性别: " << "女" << endl;
}
temp_ptr = temp;
break;
}
if (temp->post == NULL) {//如果下一个列表后就没有链表就表示结束
cout << "你创建的表中不含有这个学生" << endl;
break;
}
}
}
else if (list->pre != NULL && list->post == NULL) {//这是表尾
struct data* temp = list;
for (;;) {
if (temp->data == NULL) {
cout << "你创建的表中不含有这个学生" << endl;
break;
}
if (temp->pre == NULL) {//如果下一个列表后就没有链表就表示结束
cout << "你创建的表中不含有这个学生" << endl;
break;
}
if (temp->data->IDcard == temp_IDcard) {
cout << "名字: " << temp->data->name << endl;
cout << "身份证号: " << temp->data->IDcard << endl;
if (temp->data->sex == boy) {
cout << "性别: " << "男" << endl;
}
else if (temp->data->sex == girl) {
cout << "性别: " << "女" << endl;
}
temp_ptr = temp;
break;
}
temp = temp->pre;
}
}
else {//这是表的中间一个节点
bool not_find_pre = false;
bool not_find_post = false;
bool not_find_curr = false;
//自己检查自己
struct data* temp = list;
if (temp->data->IDcard == temp_IDcard) {
cout << "名字: " << temp->data->name << endl;
cout << "身份证号: " << temp->data->IDcard << endl;
if (temp->data->sex == boy) {
cout << "性别: " << "男" << endl;
}
else if (temp->data->sex == girl) {
cout << "性别: " << "女" << endl;
}
temp_ptr = temp;
}
else {
not_find_curr = true;
}
//向前检索
temp = list;
for (;;) {
temp = temp->pre;
if (temp->data->IDcard == temp_IDcard) {
cout << "名字: " << temp->data->name << endl;
cout << "身份证号: " << temp->data->IDcard << endl;
if (temp->data->sex == boy) {
cout << "性别: " << "男" << endl;
}
else if (temp->data->sex == girl) {
cout << "性别: " << "女" << endl;
}
temp_ptr = temp;
break;
}
if (temp->pre == NULL) {//如果下一个列表后就没有链表就表示结束
not_find_pre = true;
break;
}
}
//向后检索
temp = list;
for (;;) {
temp = temp->post;
if (temp->data->IDcard == temp_IDcard) {
cout << "名字: " << temp->data->name << endl;
cout << "身份证号: " << temp->data->IDcard << endl;
if (temp->data->sex == boy) {
cout << "性别: " << "男" << endl;
}
else if (temp->data->sex == girl) {
cout << "性别: " << "女" << endl;
}
temp_ptr = temp;
break;
}
if (temp->data == NULL) {
cout << "你创建的表中不含有这个学生" << endl;
break;
}
if (temp->post == NULL) {//如果下一个列表后就没有链表就表示结束
not_find_post = true;
break;
}
}
if (not_find_curr && not_find_pre && not_find_post) {
cout << "你创建的表中不含有这个学生" << endl;
}
}
}
return temp_ptr;
}
void delete_student(struct data** list, string name) {
struct data* search_result = search_student(*list, name);
if (search_result != NULL) {
//交接节点
struct data* pre = search_result->pre;
struct data* post = search_result->post;
//记得更新list,防止list被删除却仍然作为表的进入器
if (pre != NULL) {
pre->post = post;
*list = pre;
}
if (post != NULL) {
post->pre = pre;
*list = post;
}
if (pre == NULL && post == NULL) {
cerr << "出现严重错误!!!如果出现这个提示表示这个程序已经完了!!" << endl;
}
//删除原有数据,释放空间
delete search_result->data;
delete search_result;
}
}
void delete_student(struct data** list, long IDcard) {
struct data* search_result = search_student(*list, IDcard);
if (search_result != NULL) {
//交接节点
struct data* pre = search_result->pre;
struct data* post = search_result->post;
pre->post = post;
post->pre = pre;
//记得更新list,防止list被删除却仍然作为表的进入器
if (pre != NULL) {
pre->post = post;
*list = pre;
}
if (post != NULL) {
post->pre = pre;
*list = post;
}
if (pre == NULL && post == NULL) {
cerr << "出现严重错误!!!如果出现这个提示表示这个程序已经完了!!" << endl;
}
//删除原有数据,释放空间
delete search_result->data;
delete search_result;
}
}
void read_file(ifstream& input) {
}
//
void write_file(ofstream& output,struct data* list) {
}
void quit_system(struct data* list) {
}
void print_list(struct data* list)
{
struct data* current = list;
struct data* pre;
struct data* post;
if (list == NULL) {
cerr << "无法打印: 因为你还没有创建任何的表!!!" << endl;
}
else {
pre = current->pre;
post = current->post;
if (current->data != NULL) {
cout << pre->data->IDcard << endl;
cout << pre->data->name << endl;
cout << pre->data->sex << endl << endl;
}
for (;;) {
if (pre != NULL && pre->data != NULL) {
cout << pre->data->IDcard << endl;
cout << pre->data->name << endl;
cout << pre->data->sex << endl << endl;
}
else {
break;
}
pre = pre->pre;
}
for (;;) {
if (post != NULL) {//表示可以向后索引
cout << post->data->IDcard << endl;
cout << post->data->name << endl;
cout << post->data->sex << endl << endl;
}
else {
break;
}
post = post->post;
}
}
};
int main() {
//初始化菜单
int option_num = sizeof(menu) / sizeof(char*);
string* menu_dynamic = new string[option_num];
for (int i = 0; i < option_num; i++) {
menu_dynamic[i] = menu[i];
}
//初始化信息
string* message_dynamic = new string;
*message_dynamic = message[0];
bool end_flag = false;
bool error_input = false;
bool secondary_menu_flag = false;
bool four_status = false;
bool five_status = false;
bool six_status = false;
//一个空表
struct data* list = NULL;
string name;//用来查询的成绩
long IDcard;
gender sex;
do {//程序的主循环
//进行第一次打印,由于没有进行任何操作所以是原始菜单
for (;;) {
if (error_input) {
*message_dynamic = message[1];
}
else {
if (secondary_menu_flag) {
*message_dynamic = message[2];
}
else {
*message_dynamic = message[0];
}
}
//刷新菜单
flush_screen(menu_dynamic, message_dynamic);
char choose = ' ';
cin >> choose;
char ch;
while ((ch = getchar()) != '\n');
if (error_input) {
if (choose >= '1' && choose <= '9') {//输入真确就可以覆盖错误并且在下一次刷新中更新massage
error_input = false;
}
}
switch (choose) {
case '1':
if (secondary_menu_flag) {
if (four_status) {
string name_student;
cout << "请输入待查询学生的姓名! :";
cin >> name_student;
char ch;
while ((ch = getchar()) != '\n');//清空缓冲区
search_student(list, name_student);
system("pause");
}
else if (five_status) {
string name_student;
cout << "请输入待删除学生的姓名!" << endl;
cin >> name_student;
char ch;
while ((ch = getchar()) != '\n');//清空缓冲区
delete_student(&list, name_student);
system("pause");
}
else if (six_status) {
cout << "打印到文件!" << endl;
system("pause");
}
}
else {
if (list == NULL) {
list = make_list();
if (list == NULL) {
cerr << "表单没有创建!!! 出现重大事故!!" << endl;
exit(EXIT_FAILURE);
}
else {
cout << "表单已经成功创建!" << endl;
}
}
else {
cout << "表单已经成功创建,请不要重复创建!!!" << endl;
}
system("pause");
}
break;
case '2':
if (secondary_menu_flag) {
if (four_status) {
cout << "请输入学生的身份证号!: " << endl;
cin >> IDcard;
while ((ch = getchar()) != '\n');
search_student(list, IDcard);
system("pause");
}
else if (five_status) {
cout << "根据身份证删除学生!" << endl;
system("pause");
}
else if (six_status) {
cout << "打印到控制台!" << endl;
print_list(list);
system("pause");
}
}
else {
}
break;
case '3':
char ch_temp;
if (list == NULL) {
cerr<<"你还没有创建列表! "<<endl;
system("pause");
}
else {
cout << "请输入学生姓名: ";
cin >> name;
while ((ch = getchar()) != '\n');
cout << "请输入学生身份证号码: ";
cin >> IDcard;
while ((ch = getchar()) != '\n');
cout << "请输入学生的性别(男/女 Y/X): ";
do {
cin >> ch;
while ((ch_temp = getchar()) != '\n');
} while (ch != 'x' && ch != 'y'&& ch != 'X' && ch != 'Y');
if (ch == 'x' || ch == 'X') {
sex = girl;
}
else {
sex = boy;
}
struct data* ptr = add_student(list, name, IDcard, sex);
list = ptr; //看来单向链表没有问题了.但是双向还是有问题.
}
break;
//查询学生展开菜单
case '4':
if (!secondary_menu_flag) {
secondary_menu_flag = true;
four_status = true;
change_menu_option(secondary_menu_flag, choose + 4 - '4', menu_dynamic, message_dynamic);//这里的choose使用整数不是很好,功能全部实现后将这个参数改成开关
flush_screen(menu_dynamic, message_dynamic);
}
break;
//删除学生菜单
case '5':
if (!secondary_menu_flag) {
secondary_menu_flag = true;
five_status = true;
change_menu_option(secondary_menu_flag, choose + 4 - '4', menu_dynamic, message_dynamic);
flush_screen(menu_dynamic, message_dynamic);
}
break;
//打印表单菜单
case '6':
if (!secondary_menu_flag) {
secondary_menu_flag = true;
six_status = true;
change_menu_option(secondary_menu_flag, choose + 4 - '4', menu_dynamic, message_dynamic);
flush_screen(menu_dynamic, message_dynamic);
}
break;
case '7':
break;
case 'Q':
case 'q':
if (!secondary_menu_flag) {
exit(EXIT_SUCCESS);
}
else {
secondary_menu_flag = false;
four_status = false;
five_status = false;
six_status = false;
change_menu_option(secondary_menu_flag, choose + 4 - '4', menu_dynamic, message_dynamic);
flush_screen(menu_dynamic, message_dynamic);
}
break;
default:
error_input = true;
break;
}
}
} while (!end_flag);
return 0;
}
|
|