【项目】学生信息管理系统

news2024/12/24 9:11:43

概述

本系统总耗时 6 6 6 天,包括 学生发展与数据驱动平台6.2.cpp学生信息.txt用户账号.txt注意事项.txt。由于代码对文件的调用使用的是相对路径,所以要求这 4 4 4 个文件都需要在同一目录。使用代码前先仔细看 注意事项
如图:
2656512631@qq.com

IDE

小熊猫C++


注意事项.txt

内容如下:

1. “学生信息.txt”、“用户账号.txt”需要用ANSI编码,否则会中文乱码。
2. “学生信息.txt”、“用户账号.txt”需要与本cpp文件处于同一目录下。
3. 尽量不要直接打开“学生信息.txt”修改信息,除非你清楚以下要求:
	3.1 学号是12位没有前导0的正数,且具有唯一性。
	3.2 “学生信息.txt”依次存储每一位学生的信息。对于某一位学生,
		依次存储学号、姓名、语文成绩、数学成绩、英语成绩和总成绩。
	3.3 如果因为某些bug导致“学生信息.txt”出现错误信息,你可以直接
		打开它修改学生信息。
4. 如果你不想改变“学生信息.txt”,运行程序的时候需要保证:
	4.1 程序开始的时候选择[n]
	4.2 弹出菜单的时候不要选择[0]
5. 同[3],“用户账号.txt”只有你清楚各项数据的含义、格式要求的时候才允许你进行手动更改。
6. 对用户账号的操作是实时更新到硬盘中的,不同于对于学生信息的操作:允许每次操作后选择是否更新到硬盘。
7. 第一个管理员权限用户账号需要手动添加到“用户账号.txt”文件中,不过现在这个文件中已经有管理员账号了,可以通过管理员来赋予普通用户管理员身份。
8. 推荐小熊猫C++运行代码,其他IDE可能会出现中文乱码现象,这就需要你自己调整编码了。
9. 当前代码功能并不完善,在我觉得代码已经够好之前,会不定时更新代码。

学生信息.txt

内容如下:

540307010223		陆长生		90		73		83		246
540307130223		叶秋白		63		45		75		183
540307250105		红缨		73		47		47		167
540307010315		石生		74		47		77		198
540307010225		石昊		98		93		32		223
540307010325		唐三		39		45		93		177
540307010327		千仞雪		82		23		99		204
540307250104		千道流		48		93		70		211
540307290130		波塞西		34		93		83		210
980654321048		唐晨		99		99		99		297
123456789452		比比东		78		80		99		257
540207010315		MXT		100		100		100		300
567643532432		卡拉米		57		45		98		200
835902340238		路人甲		60		60		60		180
323290480824		路人乙		70		70		70		210
843492304421		路人丙		65		65		65		195
555555553826		小白		99		99		99		297
540207010312		Github		59		100		100		259
666666666666		麦克阿瑟		100		59		100		259
114514114514		一二三四五六七	100		60		79		239

用户账号.txt

内容如下:

100000		password2656		1		你学号是什么?		542207010315
1000000		password1		0		MXT的学号是什么?		542207010315
100000023		password331		0		MXT是几班的(输入一个1~3内的整数)?		3
2656512631		11111111aaaa		0		huanzi是谁?		WH
114546		114546a123		0		lsq是谁?		zheshidaan

学生发展与数据驱动平台6.2.cpp

C o d e Code Code

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <iomanip> // 包含C++的格式化输出库函数setw()
#include <fstream> // 包含用于文件读入、写入的类“ifstream”
#include <sstream> // 包含用于按照空格分离字符串的类“stringstream”
#include <string>
#include <vector>
#include <ctime> // 用于实时输出时间
#include <map>
#define int long long // 全局的整型均为long long
using namespace std;
const int inf = 1e18;

struct student{
	int id; // 学号
	string name; // 姓名
	int Chinese; // 语文成绩
	int math; // 数学成绩
	int English; // 英语成绩
	int sum; // 总成绩
};

class User{
public:
	long long ID; // 账号 account number(6~10位正整数)
	string password; // 8~16位,含有数字和字母,字符只能是ASCII表33~126范围内
	bool admin; // 是否拥有管理员权限
	string question; // 找回密码时的问题(不含空格的字符串[长度1~40])
	string answer; // 找回密码时的答案(不含空格的字符串[长度1~40])
};

bool cmp_id_in(student x, student y) {
	return x.id < y.id;
}
bool cmp_id_de(student x, student y) {
	return x.id > y.id;
}
bool cmp_sum_in(student x, student y) {
	return x.sum < y.sum;
}
bool cmp_sum_de(student x, student y) {
	return x.sum > y.sum;
}

void log_in(); // 使用账号登录(普通账号,管理员账号)
void startup_welcome(); // 欢迎页面
void add_student(int add_num, int first_ist_idx); // 有add_num组学生信息需要添加,从指定位置开始依次向后插入

void get_all_student(); // 输出所有学生的信息
void sorted_in_id(); // 按照学号排序
void sorted_in_sum(); // 按照总成绩排序
void change_in_id(); // 按照学号批量修改信息
void change_in_name(); // 按照姓名批量修改信息

void change_single(int idx); // 修改students[i]的各项信息
void delete_in_id(); // 按照学号批量删除学生的信息
void delete_in_name(); // 按照姓名批量删除学生的信息
void find_in_id(); // 按学号查找学生信息
void find_in_name(); // 按姓名查找学生信息
int is_integer(string str); // 如果str代表一个整数,返回这个整数;否则返回-inf
int line_number(); // 直到读取一行代表一个数字的字符串,返回这个数字
string line_string(); // 直到读取一行不含空格的字符串,返回这个字符串

void print_in_idx(int idx);// 输出students[i]学生的信息
void print_list_head(); // 输出表头
void read_information(); // 读入硬盘中的学生信息
void save_information(); // 把学生信息保存到硬盘
string change_for_output(string s); // 字符串长度超过8的部分用"..."代替
string get_now_time(); // 返回一个格式化的时间字符串
void EXIT(){cout << "程序已退出\n";exit(0);} // 退出系统

bool password_format(string s); // 判断这个字符串是否符合密码的格式要求
void read_user_id(); // 读入账号密码
void save_user_id(); // 保存账号密码
int find_account_number(int numb); // 返回账号在数组中下标,不存在则返回-1
void backstage(); // 管理员专属后台,可以对用户账号进行操作
void get_all_users(); // 输出所有用户的信息
void print_in_idx_user(int idx); // 输出us[i]用户的信息

void change_user_rights(); // 改变某个用户的权限
void delete_in_id_users(); // 按照账号批量删除用户

vector <student> students; // 保存所有的学生信息
vector <User> us; // 保存用户信息(账号、密码、密保信息、权限)
bool ADMIN = 0; // 当前用户是否拥有管理员权限
map<int, int> mp_id; // 标记存在的学号

signed main() {
	system("color 0F");
	log_in();
	return 0;
}

void log_in() {
	read_user_id();
	while (1) {
		cout << "\n---请输入你的账号密码---\n";
		cout << "其他选项:[-1]退出系统,[0]找回密码,[1]注册账号\n";
		cout << "账号->";
		int op = line_number();
		if (op == -1) {
			cout << "你选择了[-1]退出系统\n";
			EXIT();
		} else if (op == 0) {
			cout << "你选择了[0]找回密码\n";
			int ID;
			while (1) {
				cout << "请输入你要找回密码的账号(6~10位正整数)->\n";
				ID = line_number();
				if (ID >= 100000 && ID <= 9999999999) {
					int found = 0;
					for (auto p : us) {
						if (p.ID == ID) {
							int num = 3;
							while (num --) {
								cout << "请回答你设置的密保问题:\n";
								cout << p.question << "\n";
								string ans; getline(cin, ans);
								if (p.answer == ans) {
									cout << "你的密码是[" << p.password << "],不要再忘了~\n";
									break;
								} else {
									if (num) {
										cout << "答案错误,还有" << num << "次机会,笨蛋~\n";
									} else {
										cout << "密码和密保都记不住,你小子真是个人才(-_- )自己去找管理员吧\n";
									}
								}
							}
							found = 1;
							break;
						}
					}
					if (found) {
						break;
					} else {
						cout << "你输入的账号不存在\n";
					}
				} else {
					cout << "你输入的账号过长或过短\n";
				}
			}
		} else if (op == 1) {
			cout << "你选了[1]注册账号\n";
			bool OK = 0;
			while (OK == 0) {
				cout << "请输入你要注册的账号(6~10位正整数)->";
				int ID = line_number();
				if (ID >= 100000 && ID <= 9999999999) {
					int found = 0;
					for (auto p : us) {
						if (p.ID == ID) {
							found = 1;
							break;
						}
					}
					if (found) {
						cout << "你要注册的账号已经存在!\n";
					} else {
						User u;
						u.ID = ID;
						while (OK == 0) {
							cout << "请输入8~16位密码,要求含有数字和字母,字符只能是ASCII表33~126范围内->";
							string pw = line_string();
							if (password_format(pw)) {
								cout << "请牢记你的密码:[" << pw << "]\n";
								u.password = pw;
								cout << "请输入密保问题(不含空格,最多50个字节)->";
								while (1) {
									u.question = line_string();
									if (u.question.size() > 50) {
										cout << "太长了\n";
									} else {
										cout << "密保问题满足要求~\n";
										break;
									}
								}
								cout << "请输入密保答案(不含空格,最多50个字节)->";
								while (1) {
									u.answer = line_string();
									if (u.answer.size() > 50) {
										cout << "太长了\n";
									} else {
										cout << "密保问题满足要求~\n";
										OK = 1;
										break;
									}
								}
								us.push_back(u);
								save_user_id();
							} else {
								cout << "你输入的密码格式不符合要求\n";
							}
						}
					}
				} else {
					cout << "你输入的账号过长或过短\n";
				}
			}
		} else {
			if (op >= 100000 && op <= 9999999999) {
				User u;
				u.ID = op;
				int idx = find_account_number(op);
				if (idx == -1) {
					cout << "账号[" << op << "]不存在\n";
				} else {
					int num = 5;
					while (num --) {
						cout << "请输入账号[" << op << "]的密码(8~16位)->";
						string pw = line_string();
						if (password_format(pw)) {
							if (us[idx].password == pw) {
								if (us[idx].admin) {
									ADMIN = 1;
								}
								cout << "欢迎登录,当前账号为$" << (ADMIN ? "管理员用户" : "普通用户") << "$\n\n";
								startup_welcome();
								return;
							} else {
								if (num) {
									cout << "密码错误还有\n" << num << "次机会,笨蛋~\n";
								} else {
									cout << "你试错次数已经用完,请重新登录QAQ\n";
									break;
								}
							}
						} else {
							cout << "你输入的密码格式不符合要求\n";
						}
					}
				}
			} else {
				cout << "你输入的账号是负数,或长度过长、过短QAQ\n";
			}
		}
	}
}

void startup_welcome() { // 主页面
	read_information();
	int save_for_every_op = -1;
	while (save_for_every_op == -1) {
		cout << "是否每次操作之后都保存信息到硬盘[y/n]?";
		string op = line_string();
		if (op == "y") {
			save_for_every_op = 1;
		} else if (op == "n") {
			save_for_every_op = 0;
		}
	}
	if (save_for_every_op == 1) {
		cout << "学生信息将在每次操作之后更新到硬盘~\n";
	} else {
		cout << "学生信息不会自动更新到硬盘。如果你需要更新,需要手动操作。\n";
	}
	system("cls");
	while (1) {
		printf("\n**********************************************************************************************\n");
		cout <<"$                             欢迎使用学生信息管理系统(时间:" << get_now_time() << ")     $\n";
		printf("$                             [1] 录入学生信息(ADMIN)                                        $\n");
		printf("$                             [2] 输出所有学生成绩                                           $\n");
		printf("$                             [3] 按学号查找学生信息                                         $\n");
		printf("$                             [4] 按姓名查找学生信息                                         $\n");
		printf("$                             [5] 按位置查找学生信息                                         $\n");
		printf("$                             [6] 按学号对学生排序                                           $\n");
		printf("$                             [7] 按总成绩对学生排序                                         $\n");
		printf("$                             [8] 按学号修改学生信息(ADMIN)                                  $\n");
		printf("$                             [9] 按姓名修改学生信息(ADMIN)                                  $\n");
		printf("$                             [10] 按学号删除某条学生信息(ADMIN)                             $\n");
		printf("$                             [11] 按姓名删除某条学生信息(ADMIN)                             $\n");
		printf("$                             [12] 在指定位置添加一条学生信息(ADMIN)                         $\n");
		if (save_for_every_op == 0)	{
			printf("$                             [0] 将学生信息写入硬盘                                         $\n");
		}
		printf("$                             [-1] 退出程序                                                  $\n");
		printf("$                             [100] 清屏                                                     $\n");
		printf("$                             [101] 进入管理员专属后台(ADMIN)                                $\n");
		printf("**********************************************************************************************\n");
		printf("请输入您的选择(-1 ~ 0,1 ~ 12,100。不能含有多余空格):\n");
		
		int wrong_numb = 0;
		string line; getline(cin, line);
		int choice = is_integer(line);
		if (save_for_every_op == 0 && choice == 0) {
			cout << "学生信息已经写入硬盘\n";
			save_information();
			continue;
		}
		switch (choice) {
			case 1:{
				if (ADMIN) {
					printf("用户选择了数字1,录入学生信息\n");
					printf("请输入录入的学生数量:\n");
					int add_num = line_number();
					add_student(add_num, students.size());
				} else {
					cout << "您没有该操作的权限亲~\n";
				}
				break;
			}
		case 2:
			printf("用户选择了数字2,查询所有数据\n");
			get_all_student();
			break;
		case 3:
			printf("用户选择了数字3,按学号查找学生信息\n");
			find_in_id();
			break;
		case 4:
			printf("用户选择了数字4,按姓名查找学生信息\n");
			find_in_name();
			break;
			case 5:{
				printf("用户选择了数字5,按位置查找学生信息\n");
				int len = students.size();
				while (1) {
					printf("请问你要查找第几个位置的学生的信息[1~%lld]?\n", len);
					int pos = line_number();
					if (pos >= 1 && pos <= len) {
						print_list_head();
						print_in_idx(pos - 1);
						break;
					} else {
						printf("是不是憨憨,让你输入的位置范围是[1~%lld],艹\n", len);
					}
				}
				break;
			}
		case 6:
			printf("用户选择了数字6,按学号排序\n");
			sorted_in_id();
			break;
		case 7:
			printf("用户选择了数字7,按总成绩排序\n");
			sorted_in_sum();
			break;
		case 8:
			if (ADMIN) {
				printf("用户选择了数字8,按学号修改学生信息\n");
				change_in_id();
			} else {
				cout << "您没有该操作的权限亲~\n";
			}
			break;
		case 9:
			if (ADMIN) {
				printf("用户选择了数字9,按姓名修改学生信息\n");
				change_in_name();
			} else {
				cout << "您没有该操作的权限亲~\n";
			}
			break;
		case 10:
			if (ADMIN) {
				printf("用户选择了数字10,按学号删除某条学生信息\n");
				delete_in_id();
			} else {
				cout << "您没有该操作的权限亲~\n";
			}
			break;
		case 11:
			if (ADMIN) {
				printf("用户选择了数字11,按姓名删除某条学生信息\n");
				delete_in_name();
			} else {
				cout << "您没有该操作的权限亲~\n";
			}
			break;
			case 12:{
				if (ADMIN) {
					printf("用户选择了数字12,在指定位置添加一条学生信息\n");
					int len = students.size();
					while (1) {
						printf("请问你要将信息添加到第几个位置[1~%lld]?\n", len + 1);
						int pos = line_number();
						if (pos >= 1 && pos <= len + 1) {
							add_student(1, pos - 1);
							break;
						} else {
							printf("是不是憨憨,让你输入的位置范围是[1~%lld],艹\n", len + 1);
						}
					}
				} else {
					cout << "您没有该操作的权限亲~\n";
				}
				break;
			}
		case -1:
			EXIT();
		case 100:
			system("cls");
			break;
		case 101:
			if (ADMIN) {
				backstage();
			} else {
				cout << "您没有该操作的权限亲~\n";
			}
			break;
		default:
			wrong_numb = 1;
			printf("请输入正确的数字\n");
		}
		if (save_for_every_op) {
			save_information();
		}
		if (wrong_numb == 0 && choice != 100) {
			int retn = 0;
			while (retn == 0) {
				cout << "若要返回主菜单,请输入[r]:\n";
				string op; getline(cin, op);
				if (op == "r") {
					retn = 1;
				}
			}
		}
	}
}

void add_student(int add_num, int first_ist_idx) {
	for (int i = 1; i <= add_num; i ++) {
		printf("请输入第%lld个学生的信息\n", i);
		
		student stu;
		printf("请输入12位学号:");
		while (1) {
			stu.id = line_number();
			if (stu.id >= 100000000000 && stu.id <= 999999999999) {
				break;
			} else {
				cout << "学号太短辣,请输入12位数字~\n";
			}
		}
		
		if (mp_id[stu.id]) {
			printf("学号已经存在!\n");
			printf("请选择:[1:重新输入][2:直接调过当前学生]:");
			int op = -1;
			while (op != 1 && op != 2) {
				op = line_number();
			}
			if (op == 1) {
				i --;
			}
			continue;
		}
		mp_id[stu.id] = 1;
		
		printf("请输入学生的名字(不能有空格):\n");
		stu.name = line_string();
		printf("请输入语文成绩:\n");
		stu.Chinese = line_number();
		printf("请输入数学成绩:\n");
		stu.math = line_number();
		printf("请输入英语成绩:\n");
		stu.English = line_number();
		
		stu.sum = stu.Chinese + stu.math + stu.English;
		
		students.insert(students.begin() + first_ist_idx ++, stu);
	}
	printf("所有学生数据已经录入\n");
}

void get_all_student() {
	print_list_head();
	int len = students.size();
	for (int i = 0; i < len; i ++) {
		print_in_idx(i);
	}
	printf("**********************************************************************************************\n\n");
}

void sorted_in_id() {
	while (1) {
		printf("根据学号按照升序还是降序排序[1:升序][2:降序]?");
		string op = line_string();
		if (op == "1") { 
			sort(students.begin(), students.end(), cmp_id_in);
			break;
		} else if (op == "2") {
			sort(students.begin(), students.end(), cmp_id_de);
			break;
		} else {
			printf("非法输入\n");
		}
	}
}

void sorted_in_sum() {
	while (1) {
		printf("根据总成绩按照升序还是降序排序[1:升序][2:降序]?");
		string op = line_string();
		if (op == "1") {
			sort(students.begin(), students.end(), cmp_sum_in);
			break;
		} else if (op == "2") {
			sort(students.begin(), students.end(), cmp_sum_de);
			break;
		} else {
			printf("非法输入\n");
		}
	}
}

void change_in_id() {
	while (1) {
		printf("请输入你需要修改信息的学号(输入-1退出按照学号修改信息程序):");
		int id = line_number();
		if (id == -1)
			break;
//		cout << "mp_id[" << id << "] = " << mp_id[id] << "\n";
		int found = 0;
		int Size = students.size();
		for (int i = 0; i < Size; i ++) {
			if (students[i].id == id) {
				change_single(i);
				found = 1;
			}
		}
		if (not found) {
			printf("[%lld]没有这个人\n", id);
		}
	}
}

void change_in_name() {
	while (1) {
		printf("请输入你需要修改信息的姓名(输入-1退出按照姓名修改信息程序):");
		string Name = line_string();
		if (Name == "-1") {
			break;
		}
		int found = 0;
		int Size = students.size();
		for (int i = 0; i < Size; i ++) {
			if (Name == students[i].name) {
				change_single(i);
				found = 1;
			}
		}
		if (not found) {
			cout << "[" << Name << "]" << "没有这个人\n";
		}
	}
}

void change_single(int idx) {
	while (1) {
		print_list_head();
		auto& [id, name, Chin, math, Engl, sum] = students[idx];
		
		cout << id << "\t\t" << name << "\t\t" << Chin << "\t\t" << math << "\t\t" << Engl << "\t\t" << sum << "\n";
		printf("输入你要修改的项:[-1:退出修改该学生的信息][0:学号][1:姓名][2:语文][3:数学][4:英语]:\n");
		int op = line_number();
		switch (op) {
		case -1:
			cout << "该学生信息的修改已结束\n";
			return;
		case 0:
			printf("输入新的12位学号:\n");
			int new_id;
			while (1) {
				new_id = line_number();
				if (new_id >= 100000000000 && new_id <= 999999999999) {
					break;
				} else {
					cout << "学号太短辣,请输入12位数字~\n";
				}
			}
			mp_id[id] = 0;
			mp_id[new_id] = 1;
			id = new_id;
			break;
			case 1:{ // switch的case里边如果要定义string字符串,需要用花括号括住这个case里边的语句
				printf("输入新姓名:\n");
				name = line_string();
				break;
			}
		case 2:
			printf("请输入新语文分数:\n");
			Chin = line_number();
			break;
		case 3:
			printf("请输入新数学分数:\n");
			math = line_number();
			break;
		case 4:
			printf("请输入新英语分数:\n");
			Engl = line_number();
			break;
		default:
			printf("就这么几个简单的数字,还能输错?\n");
		}
		sum = Chin + math + Engl;
	}
}

void delete_in_id() {
	printf("请依次输入要删除的学生的学号,以[回车]隔开。输入[-1]结束。\n");
	while (1) {
		int id_delete = line_number();
		if (id_delete == -1) {
			printf("信息删除系统即将退出\n");
			return;
		}
		if (mp_id[id_delete]) {
			mp_id[id_delete] = 0;
			int len = students.size();
			for (int i = 0; i < len; i ++) {
				if (students[i].id == id_delete) {
					students.erase(students.begin() + i);
					cout << "该学生信息已删除\n";
					break;
				}
			}
		} else {
			printf("系统中不存在学号为%lld的学生\n", id_delete);
		}
	}
}

void delete_in_name() {
	printf("请依次输入要删除的学生的姓名,以[回车]隔开。输入[-1]结束。\n");
	while (1) {
		string name_delete = line_string();
		if (name_delete == "-1") {
			printf("信息删除系统即将退出\n");
			return;
		}
		int found = 0;
		int len = students.size();
		for (int i = 0; i < len; i ++) {
			if (students[i].name == name_delete) {
				found = 1;
				printf("找到学号为%lld的学生,输入[y]删除该学生信息,", students[i].id);
				printf("输入[-1]退出信息删除系统,输入其他跳过该学生:\n");
				string op = line_string();
				if (op == "y") {
					mp_id[students[i].id] = 0;
					students.erase(students.begin() + i);
					i --;
					len --;
					cout << "该学生信息已删除\n";
				} else if (op == "-1") {
					return;
				} else {
					continue;
				}
			}
		}
		if (not found) {
			cout << "系统中不存在名字是[" << name_delete << "]的学生\n";
		}
	}
}

int is_integer(string str) { // 如果str代表一个整数且-1e12<=numb<=1e12,返回这个整数;否则返回-inf
//	cout << "str:[" << str << "]\n";
	int number = 0;
	int not_number = 0;
	int res = 0;
	for (auto p : str) {
		if (p >= '0' && p <= '9') {
			number ++;
			res = res * 10 + p - '0';
		} else {
			not_number ++;
		}
	}
	if ((not_number == 0 || (number && not_number == 1 && str[0] == '-')) && number <= 12) { // str代表一个整数
		if (str[0] == '-')	return -1 * res;
		return res;
	} else {
		return -inf;
	}
}

void find_in_id() {
	printf("请输入要查询的学生的学号,以空格隔开。输入[-1]结束。\n");
	string line;
	getline(cin, line); // 读入一行字符串
	stringstream line_stream; // 字符串数据流,可以从中读取数据,也可以将数据写入到其中
	line_stream.str(line); // 将line当做一个数据流存储到linestream字符串中
	string id_find;
	print_list_head();
	vector <string> a;
	while (line_stream >> id_find) {
		if (id_find == "-1") {
			printf("信息查询系统即将退出\n");
			break;
		}
		int x = is_integer(id_find);
		if (x >= 0) { // 输入的学号是自然数/即有可能作为一个学号
			if (mp_id[x]) {
				int len = students.size();
				for (int i = 0; i < len; i ++) {
					if (students[i].id == x) {
						print_in_idx(i); // 输出这个学生的数据
						break;
					}
				}
			} else {
				string s = "[" + to_string(x) + "]对应的学生不存在\n";
				a.emplace_back(s);
			}
		} else {
			string s = "[" + id_find +"]学号只能是12位正整数\n";
			a.emplace_back(s);
		}
	}
	for (auto p : a) cout << p;
}

void find_in_name() {
	printf("请输入要查找的学生的姓名,以空格隔开。输入[-1]结束。\n");
	string line;
	getline(cin, line); // 读入一行字符串
	stringstream line_stream; // 字符串数据流,可以从中读取数据,也可以将数据写入到其中
	line_stream.str(line); // 将line当做一个数据流存储到linestream字符串中
	string name_find;
	print_list_head();
	vector <string> a;
	while (line_stream >> name_find) {
		if (name_find == "-1") {
			printf("信息查找系统即将退出\n");
			break;
		}
		int found = 0;
		int len = students.size();
		for (int i = 0; i < len; i ++) {
			if (students[i].name == name_find) {
				print_in_idx(i);
				found = 1;
			}
		}
		if (found == 0) {
			string s = "[" +name_find + "]这个人不存在\n";
			a.emplace_back(s);
		}
	}
	for (auto p : a) cout << p;
}

void print_in_idx(int idx) {
	auto [id, name, Chin, math, Engl, sum] = students[idx];
	cout << id << "\t\t" << left << setw(16) << change_for_output(name) << Chin << "\t\t" << math << "\t\t" << Engl << "\t\t" << sum << "\n";
}

void print_list_head() {
	printf("\n**********************************************************************************************\n");
	printf("学号\t\t\t姓名\t\t语文\t\t数学\t\t英语\t\t总成绩\n");
}

void read_information() { // 读入硬盘内容(学生信息)
	ifstream ip_file;
	ip_file.open("学生信息.txt");
	if (ip_file.is_open()) {
		int id_read;
		while (ip_file >> id_read) {
			string name;
			int Chin, math, Engl, sum;
			ip_file >> name >> Chin >> math >> Engl >> sum;
			students.push_back({id_read, name, Chin, math, Engl, sum});
			mp_id[id_read] = 1;
		}
		ip_file.close();
	} else {
		cout << "无法读取硬盘中的学生信息!\n";
	}
}

void save_information() { // 保存学生信息到硬盘
	ofstream op_file;
	op_file.open("学生信息.txt");
	if (op_file.is_open()) {
		for (auto p : students) {
			auto [id, name, Chin, math, Engl, sum] = p;
			op_file << id << "\t\t" << left << setw(16) << 
			name << Chin << "\t\t" << math << "\t\t" << Engl << "\t\t" << sum << "\n";
		}
		op_file.close();
	} else {
		cout << "无法保存学生信息到硬盘!\n";
	}
}

int line_number() {
	while (1) {
//		cin.ignore(); // 忽略一个字符,通常用于忽略回车键或换行符
		string s; getline(cin, s);
		if (is_integer(s) == -inf) { // 如果s代表的数字不在[-1e12, 1e12]范围内,或表示的不是一个数字
			cout << "输入的内容不是数字,或者数字过长,请重新输入\n";
		} else {
			return is_integer(s);
		}
	}
}

string line_string() {
	while (1) {
		string s; getline(cin, s);
		if (s.find(' ') == s.npos) {
			return s;
		} else {
			cout << "输入的内容含有空格,请重新输入\n";
		}
	}
}

string change_for_output(string s) {
	return s.substr(0, 8) + (s.size() > 8 ? "..." : "");
}

string get_now_time() { // 返回一个格式化的时间字符串
	time_t timer;
	struct tm *now;
	time(&timer);
	now = localtime(&timer);
	string s = asctime(now);
	return s.substr(0, s.size() - 1);
}

void read_user_id() {
	ifstream ip_file;
	ip_file.open("用户账号.txt");
	if (ip_file.is_open()) {
		int id_read;
		while (ip_file >> id_read) {
			string password;
			bool admin;
			string question, answer;
			ip_file >> password >> admin >> question >> answer;
			us.push_back({id_read, password, admin, question, answer});
		}
		cout << "账号信息读取完毕~\n";
		ip_file.close();
	} else {
		cout << "无法读取硬盘中的账号信息!\n";
	}
}

void save_user_id() {
	ofstream op_file;
	op_file.open("用户账号.txt");
	if (op_file.is_open()) {
		for (auto p : us) {
			auto [id, pw, ad, qu, an] = p;
			op_file << id << "\t\t" << pw << "\t\t" << ad << "\t\t" << qu << "\t\t" << an << "\n";
		}
	} else {
		cout << "无法保存用户账号到硬盘\n";
	}
}

bool password_format(string s) { // 8~16位,含有数字和字母,字符只能是ASCII表33~126范围内
	if (s.size() < 8 || s.size() > 16)
		return 0;
	int ok = 1;
	int number = 0;
	int letter = 0;
	for (auto p : s) {
		if (p < 33 || p > 126) {
			ok = 0;
			break;
		}
		if (p >= 'a' && p <= 'z' || p >= 'A' && p <= 'Z') {
			letter ++;
		}
		if (p >= '0' && p <= '9') {
			number ++;
		}
	}
	return ok && number && letter;
}

int find_account_number(int numb) {
	int len = us.size();
	for (int i = 0; i < len; i ++) {
		if (us[i].ID == numb) {
			return i;
		}
	}
	return -1;
}

void backstage() { // 管理员专属后台,可以对用户账号进行操作
	while (1) {
		system("cls");
		cout << "\n**********************************************************************************************\n";
		cout << "$             尊贵的管理员,您已经进入用户账号管理后台(时间:" << get_now_time() << ")     $\n";
		cout << "$                             [101] 输出用户列表(ADMIN)                                      $\n";
		cout << "$                             [102] 改变用户权限(ADMIN)                                      $\n";
		cout << "$                             [103] 按照账号批量删除用户(ADMIN)                              $\n";
		cout << "$                             [-1] 退出用户账号管理后台(ADMIN)                               $\n";
		cout << "**********************************************************************************************\n";
		cout << "请输入您的选择(101~103。不能含有多余空格):\n";
		string line; getline(cin, line);
		int choice = is_integer(line);
		int wrong_numb = 0;
		switch (choice) {
		case 101:
			cout << "你选择了[101] 输出用户列表\n";
			get_all_users();
			break;
		case 102:
			cout << "你选择了[102] 改变某个用户权限\n";
			change_user_rights();
			break;
		case 103:
			cout << "你选择了[103] 按照账号批量删除用户\n";
			delete_in_id_users();
			break;
		case -1:
			system("cls");
			cout << "用户账号管理后台已经退出\n";
			return;
		default:
			printf("请输入正确的数字\n");
			wrong_numb = 1;
			break;
		}
		save_user_id();
		if (wrong_numb == 0) {
			int retn = 0;
			while (retn == 0) {
				cout << "若要返回用户后台菜单,请输入[r]:\n";
				string op; getline(cin, op);
				if (op == "r") {
					retn = 1;
				}
			}
		}
	}
}

void print_in_idx_user(int idx) {
	auto [id, pw, ad, mbwt, mbda] = us[idx];
	cout << left << setw(12) << id << left << setw(20) << pw << left << setw(12) << ad;
	cout << left << setw(50) << mbwt << mbda << "\n";
}

void get_all_users() {
	cout << "\n$**************************************************************************************";
	cout << "**************************$\n";
	cout << left << setw(12) << "账号" << left << setw(20) << "密码" << left << setw(12) << "管理员权限";
	cout << left << setw(50) << "密保问题" << "密保答案" << "\n";
	int len = us.size();
	for (int i = 0; i < len; i ++) {
		print_in_idx_user(i);
	}
	cout << "$****************************************************************************************";
	cout << "************************$\n\n";
}

void change_user_rights() { // 改变某个用户的权限
	while (1) {
		cout << "请输入你要改变权限的用户的账号(6~10位正整数,输入[-1]退出操作):";
		int id = line_number();
		if (id == -1) {
			cout << "[改变用户权限]操作即将退出\n";
			return;
		} else if (id >= 100000 && id <= 9999999999) {
			int idx = find_account_number(id);
			if (idx == -1) {
				cout << "该账号不存在\n";
			} else {
				us[idx].admin ^= 1;
				if (us[idx].admin) {
					cout << "已赋予账号[" << id << "]管理员权限^_^\n";
				} else {
					cout << "已取消账号[" << id << "]管理员权限QAQ\n";
				}
				return;
			}
		} else {
			cout << "你输入的账号是负数,或长度过长、过短QAQ\n";
		}
	}
}

void delete_in_id_users() { // 按照账号批量删除用户
	printf("请依次输入要删除的用户的账号,以[回车]隔开。输入[-1]结束。\n");
	while (1) {
		int id_delete = line_number();
		if (id_delete == -1) {
			printf("信息删除系统即将退出\n");
			return;
		}
		int idx = find_account_number(id_delete);
		if (idx != -1) {
			us.erase(us.begin() + idx);
			cout << "账号[" << id_delete << "[已删除\n";
			return;
		} else {
			cout << "系统中不存在账号为[" << id_delete << "]的账号\n"; 
		}
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1293015.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录算法训练营 ---第五十八天

今天开启单调栈的征程。 第一题&#xff1a; 简介&#xff1a; 本题有两种解法&#xff0c;第一种&#xff1a;暴力破解 两层for循环 时间复杂度为O(n^2) 超时了 第二种&#xff1a;单调栈解法也是今天的主角。 单调栈是什么&#xff1f; 单调递增栈&#xff1a;单调递增栈…

Centos7部署Graylog5.2日志系统

Graylog5.2部署 Graylog 5.2适配MongoDB 5.x~6.x&#xff0c;MongoDB5.0要求CPU支持AVX指令集。 主机说明localhost部署Graylog&#xff0c;需要安装mongodb-org-6.0、 Elasticsearch7.10.2 参考&#xff1a; https://blog.csdn.net/qixiaolinlin/article/details/129966703 …

22 查找众数及中位数

题目描述 众数是指一组数据中出现次数量多的那个数&#xff0c;众数可以是多个。 中位数9是指把一组数据从小到大排列&#xff0c;最中间的那个数&#xff0c;如果这组数据的个数是奇数&#xff0c;那最中间那个就是中位数&#xff0c;如果这组数据的个数为偶数&#xff0c;那就…

tomcat环境搭建

镜像下载地址&#xff1a;https://mirror.tuna.tsinghua.edu.cn/apache/tomcat/ 配置环境变量 添加系统变量 编辑Path 测试 dos窗口运行startup启动tomcat 访问http://localhost:8080/

2023年最新prometheus + grafana搭建和使用

一、安装prometheus 1.1 安装 prometheus官网下载地址 sudo -i mkdir -p /opt/prometheus #移动解压后的文件名到/opt/,并改名prometheus mv prometheus-2.45 /opt/prometheus/ #创建一个专门的prometheus用户&#xff1a; -M 不创建家目录&#xff0c; -s 不让登录 useradd…

YITH WooCommerce Product Bundles Premium电商商城产品捆绑销售高级版

点击阅读YITH WooCommerce Product Bundles Premium电商商城产品捆绑销售高级版原文 YITH WooCommerce Product Bundles Premium电商商城产品捆绑销售高级版的作用是在您的商店中创建特别优惠&#xff0c;将产品捆绑在一起提供折扣和特价。 您如何从中受益&#xff1a; 您将…

YOLO的全面综述:从YOLOv1到最新版本

文章目录 摘要1、简介2、YOLO在不同领域的应用3、目标检测的度量标准和非最大值抑制&#xff08;NMS&#xff09;3.1. AP如何工作&#xff1f;3.2. 计算AP3.3、非极大值抑制&#xff08;NMS&#xff09; 4、YOLO: You Only Look Once4.1、YOLOv1的工作原理4.2、YOLOv1架构4.3、…

数学术语之源——全纯函数(holomorphic)

1. “holomorphic” 和 “meromorphic”的词源 术语“全纯函数(holomorphic function)”和“亚纯函数(meromorphic function)”由Charles A. A. Briot (1817-1882) 和Jean-Claude Bouquet (1819-1885)在<<椭圆函数理论>>(Thorie des fonctions elliptiques)(1859年…

月薪6W!美团、网易等大厂急招HarmonyOS开发!

近期&#xff0c;多家互联网公司发布了多个和鸿蒙系统有关的岗位。 不仅如此&#xff0c;还与Windows等主流老牌操作系统并列&#xff0c;并且排在首位介绍。 此外&#xff0c;今日头条招聘Android开发工程师也提及岗位需要“负责今日头条 Android、鸿蒙系统等新技术方向调研…

怎么压缩过大的GIF动图?三种方法随心选!

GIF图片由于其图片格式&#xff0c;本身就会很大&#xff0c;但是微信QQ还有一些其他的社交平台对上传的表情包是有限制的&#xff0c;这个时候就需要借助一些图片处理工具对GIF进行压缩。 下面就向大家介绍三种好用的方法并展示具体的操作步骤。 一、使用嗨格式压缩大师进行压…

WPS论文写作——公式和公式序号格式化

首先新建一个表格&#xff0c;表格尺寸按你的需求来确定&#xff0c;直接 插入--》表格 即可。 然后在表格对应位置填上公式&#xff08;公式要用公式编辑器&#xff09;和公式序号&#xff0c;然后可以按照单独的单元格或者整行或整列等来设置样式&#xff0c;比如居中对齐、…

图像处理之把模糊的图片变清晰

1.图片如果是有雾化效果的对图像产生影响的,要先进行图形增强,Retinex是基于深度神经网络了,我在之前图形处理的文章一路从神经网络(概率统计)—>积卷神经网络(对区域进行概率统计,对图片进行切割多个识别对象)–>深度积卷神经网络(RetinexNet也是模拟人脑的处理过程,增加…

常见的Bean工厂后置处理器

此代码在jdk11上测试通过&#xff0c;SpringBoot版本为2.7.14 1.上代码 导入坐标 <dependencies><!-- spring数据坐标 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-rest</art…

音视频学习(二十)——rtsp收流(udp方式)

前言 本文主要介绍通过udp方式实现rtsp拉流。 流程图 流程说明&#xff1a; 相较于tcp方式“信令数据”复用同一连接拉流&#xff0c;udp方式拉流“信令数据”采用不同的连接&#xff0c;信令传输采用tcp&#xff0c;流数据传输采用udp&#xff1b;客户端向服务端&#xff0…

二维码智慧门牌管理系统升级:行政区划维护功能详解

文章目录 前言一、行政区划维护解决方案二、解决方案优势 前言 随着科技不断发展&#xff0c;二维码智慧门牌管理系统已成为物业管理和社区服务等领域的重要工具。在此系统升级解决方案中&#xff0c;行政区划维护功能愈发显得重要。我们将详细介绍这一功能&#xff0c;助您更…

看好美国跨境电商平台Etsy的三个理由

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 不可否认&#xff0c;最近的经济低迷给美国跨境电商平台Etsy(ETSY)的增长带来了一些麻烦。虽然Etsy第三季度营收同比增长了7%&#xff0c;但其商品总量仅增长了1%。如果没有有利的汇率&#xff0c;Etsy的销售额基本上会与前…

【赠书活动】Java程序员,你掌握了多线程吗?

文章目录 摘要01 多线程对于Java的意义02 为什么Java工程师必须掌握多线程03 Java多线程使用方式04 如何学好Java多线程赠书活动 摘要 互联网的每一个角落&#xff0c;无论是大型电商平台的秒杀活动&#xff0c;社交平台的实时消息推送&#xff0c;还是在线视频平台的流量洪峰&…

名创优品股份有限公司

用户简介 名创优品股份有限公司&#xff08;以下简称&#xff1a;名创优品&#xff09;奉行“简约、自然、富质感”的生活哲学和“回归自然&#xff0c;还原产品本质”的设计主张&#xff0c;秉承“尊重消费主义者”的品牌精神&#xff0c;致力于为全球消费者提供真正“优质、…

Avalonia中如何实现文件拖拽上传

前言 前面我们讲了在Avalonia中如何将View事件映射到ViewModel层感兴趣的读者可以看一下&#xff0c;本章我们将讲一下在Avalonia框架下如何实现文件和文字的拖拽到指定区域进行处理和上传。 先看效果 界面设计比较简单&#xff0c;还是在前一张的基础上加了一个指定区域&…

十六、FreeRTOS之FreeRTOS队列集

本节需要掌握以下内容&#xff1a; 1&#xff0c;队列集简介&#xff08;了解&#xff09; 2&#xff0c;队列集相关API函数介绍&#xff08;熟悉&#xff09; 3&#xff0c;队列集操作实验&#xff08;掌握&#xff09; 一、队列集简介&#xff08;了解&#xff09; 一个…