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

概述

本系统总耗时 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"; 
		}
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据分析基础之《matplotlib(4)—柱状图》

一、柱状图绘制 1、柱状图要素 有类别 2、需求&#xff1a;对比每部电影的票房收入 电影数据如下图所示&#xff1a; 3、matplotlib.pyplot.bar(x, height, width0.8, bottomNone, *, aligncenter, dataNone, **kwargs) 说明&#xff1a; x&#xff1a;有几个类别 height&am…

ROS小练习——参数设置

目录 一、参数名获取 二、参数修改 1、代码修改 C python 2、命令行修改 3、启动时修改 4、launch文件传参修改 一、参数名获取 rosparam list 二、参数修改 1、代码修改 C #include "ros/ros.h"int main(int argc, char *argv[]) {ros::init(argc,argv,…

接口自动化测试之Yaml数据驱动封装!

一、数据驱动&#xff1a;pytest.mark.parametrize(&#xff09; 首先看个样本&#xff1a; import pytestclass TestData:# parametrize有两个值&#xff0c;一个是args_name:参数名&#xff0c;一个是args_value:参数值,可以有多个&#xff0c;进行数据解包# args_value可以…

智慧农业技术解决方案:PPT全文32页,附下载

关键词&#xff1a;智慧农业解决方案&#xff0c;数字农村&#xff0c;数字农业&#xff0c;智慧农业大数据平台&#xff0c;智慧农业技术方案 一、智慧农业技术平台建设方案 1、全球化和信息化趋势 随着全球化和信息化的加速发展&#xff0c;农业领域也面临着前所未有的挑战…

5分钟搞懂ECN

ECN是通过在IP和TCP头中携带拥塞信息&#xff0c;通知发送方网络拥塞状态&#xff0c;从而采取相应拥塞控制措施。原文: What is ECN(Explicit Congestion Notification)?[1] ECN是Explicit Congestion Notification的缩写&#xff0c;意思是显式拥塞通知算法&#xff0c;和慢…

【LeetCode】2621. 睡眠函数

睡眠函数 Promise异步 题目题解 题目 请你编写一个异步函数&#xff0c;它接收一个正整数参数 millis &#xff0c;并休眠 millis 毫秒。要求此函数可以解析任何值。 示例 1&#xff1a; 输入&#xff1a;millis 100 输出&#xff1a;100 解释&#xff1a; 在 100ms 后此异步…

Java多线程:代码不只是在‘Hello World‘

Java线程好书推荐 概述01 多线程对于Java的意义02 为什么Java工程师必须掌握多线程03 Java多线程使用方式04 如何学好Java多线程写在末尾&#xff1a; 主页传送门&#xff1a;&#x1f4c0; 传送 概述 摘要&#xff1a;互联网的每一个角落&#xff0c;无论是大型电商平台的秒杀…

<JavaEE> 多线程编程中的“等待和通知机制”:wait 和 notify 方法

目录 一、等待和通知机制的概念 二、wait() 方法 2.1 wait() 方法的使用 2.2 超时等待 2.3 异常唤醒 2.4 唤醒等待的方法 三、notify() 方法 四、notifyAll() 方法 五、wait 和 sleep 的对比 一、等待和通知机制的概念 1&#xff09;什么是等待和通知机制&#xff1f…

若依框架的搭建

若依框架 若依框架的搭建&#xff08;前后端分离版本&#xff09;环境要求IDEA拉取Gitee源码Mysql 配置Redis 配置后端启动前端配置问题解决 效果展示 若依框架的搭建&#xff08;前后端分离版本&#xff09; 简介 RuoYi-Vue 是一个 Java EE 企业级快速开发平台&#xff0c;基…

线程池(Linux +C)

参考 手写线程池 - C语言版 | 爱编程的大丙 (subingwen.cn) 目录 1.为什么需要线程池&#xff1f; 1&#xff09;线程问题&#xff1a; 2&#xff09;如何解决线程问题&#xff08;线程池的优势&#xff09;&#xff1a; 2.线程池是什么&#xff1f; 1&#xff09;线程的…

无公网IP环境Windows系统使用VNC远程连接Deepin桌面

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…

Hadoop学习笔记(HDP)-Part.19 安装Kafka

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

使用pandas制作图表

数据可视化对于数据分析的重要性不言而喻&#xff0c;一个优秀的图表有足以一眼就看出关键所在。pandas利用matplotlib实现绘图。能够提供各种各样的图表功能&#xff0c;包括: 单折线图多折线图柱状图叠加柱状图水平叠加柱状图直方图拆分直方图箱型图区域块图形散点图饼图多子…

Linux AMH服务器管理面板本地安装与远程访问

最近&#xff0c;我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念&#xff0c;而且内容风趣幽默。我觉得它对大家可能会有所帮助&#xff0c;所以我在此分享。点击这里跳转到网站。 文章目录 1. Linux 安装AMH 面板2. 本地访问AMH 面板3. Linux安装…

MySQL老是卸载不干净,不会删除注册表,安装总是报错

给大家推荐一款非常使用的工具 geek点击官网下载。 安装完成主页就长这样&#xff1a; 右键点击你要删除的MySQL卸载即可。自动帮你清空注册表等信息。 谁用谁知道&#xff01;&#xff01;&#xff01; 用了感觉不错的话记得回来给我点赞加评论哦&#xff01;&#xff01;&…

科普小知识-3D 打印是什么?

3D 打印是什么&#xff1f;作为近年来备受关注的前沿科技&#xff0c;3D 打印技术正在不断改变着制造业、医疗领域、艺术设计等多个领域的面貌。其又被称为增材制造&#xff0c;是一种通过电脑设计&#xff0c;逐层堆叠材料来创建三维物体的技术。 3D 打印的基本原理 3D 打印…

数据库的索引

索引的特点 1&#xff09;加快查询的速度 2&#xff09;索引自身是一种数据结构&#xff0c;也要占用存储空间 3&#xff09;当我们需要进行增删改的时候&#xff0c;也要对索引进行更新&#xff08;也需要额外的空间开销&#xff09; sql操作 查看索引 show index from …

安装postgresql驱动及python使用pyodbc指定postgresql驱动调用postgresql

注&#xff1a;Python解释器版本(32位/64位)和postgresql驱动版本(32位/64位)需一致。 一、安装postgresql驱动 https://www.postgresql.org/ftp/odbc/versions/msi/ &#xff08;1&#xff09;32位&#xff1a; &#xff08;2&#xff09;64位&#xff1a; 双击安装。全程默…

如何让软文更具画面感,媒介盒子分享

写软文这种带有销售性质的文案时&#xff0c;总说要有画面感&#xff0c;要有想象空间。只有针对目标用户的感受的设计&#xff0c;要了解用户想的是什么&#xff0c;要用可视化的描述来影响用户的感受&#xff0c;今天媒介盒子就和大家分享&#xff1a;如何让软文更具画面感。…

axios调接口传参特殊字符丢失的问题(encodeURI 和 encodeURIComponent)

1、axios调接口特殊字符丢失的问题 项目开发过程中遇到一个接口传参&#xff0c;参数带特殊字符&#xff0c;axios调接口特殊字符丢失的问题 例如接口&#xff1a; get/user/detail/{name} name是个参数直接调接口的时候拼到接口上&#xff0c;get/user/detail/test123#$%&am…