数据结构课设-学生信息管理系统

#include<stdio.h>
#include<iostream>
#include<fstream>
#include<string>
#include <vector>
#include<sstream>
#include<algorithm>
using namespace std;

//定义结构体,以便接下来对学生成绩进行排序
struct Student {
	std::string line; // 保存原始行内容
	int score;        // 保存第m个字段的分数
	int sum;			//总成绩使用
	//double average;		//平均分使用

	// 定义自定义比较运算符,用于排序
	bool operator<(const Student& other) const {
		return score > other.score;
	}
};

struct Student_Beifen {
	std::string line;
	double average;

	bool operator<(const Student_Beifen& other) const {
		return average > other.average; // 按平均数降序排列
	}
};



//总成绩函数
void FileContSum() {
	std::string filename = "./filename.txt";
	std::ifstream inputFile(filename); // 打开文件以读取内容
	std::string line;
	while (std::getline(inputFile, line)) {
		std::istringstream iss(line);
		std::vector<std::string> fields;
		std::string field;
		while (iss >> field) {
			fields.push_back(field);
		}

		int sum = 0;
		for (int i = fields.size() - 3; i < fields.size(); ++i) {
			sum += std::stoi(fields[i]);
		}

		line += " " + std::to_string(sum); // 将和追加到每行的末尾
		std::cout << line << std::endl; // 输出带有和的每行内容
	}

	inputFile.close(); // 关闭文件
}



//文件读取函数
void FileR(){	
	std::ifstream file("./filename.txt"); // 打开文件

	if (file.is_open()) { // 检查文件是否成功打开
		std::string line;
		while (std::getline(file, line)) { // 逐行读取文件内容
			std::cout << line << std::endl; // 输出每一行内容
		}
		file.close(); // 关闭文件
	}
	else {
		std::cout << "无法打开文件" << std::endl;
	}
}

//写入文件函数
void FileW() {

	std::ofstream file("./filename.txt", std::ios::app); // 打开文件并追加内容

	if (file.is_open()) { // 检查文件是否成功打开
		std::string input;
		std::cout << "请按照<学号 姓名 性别 班级 数据结构 Linux编程 算法设计与分析>顺序输入该学生信息及成绩(以EOF结束):" << std::endl;
		while (std::getline(std::cin, input)) { // 逐行读取用户输入
			if (input == "EOF") {
				FileContSum();					//BUG,调用该函数会导致刚写入的成绩信息前面有一行空格
				break; // 输入 EOF 结束循环
			}
			file << input << std::endl; // 追加内容到文件末尾
		}
		file.close(); // 关闭文件
		std::cout << "成绩录入完成" << std::endl;
	}
	else {
		std::cout << "无法打开文件" << std::endl;
	}
}

//文件内容删除函数
void FileContDel(long long int student_id) {
	std::string strstudent_id = std::to_string(student_id);		//把long long int 转化为str类型,否则下面将无法匹配
	std::string filename = "./filename.txt";
	std::ifstream inputFile(filename); // 打开文件以读取内容
	std::vector<std::string> lines; // 存储文件的每一行内容
	std::string line;
	while (std::getline(inputFile, line)) {
		std::string firstPart;
		std::istringstream isse(line);
		isse >> firstPart; // 读取每一行开头的数字部分

		if (firstPart != strstudent_id) { // 如果不是目标行,则将其存储在 vector 中
			lines.push_back(line);
		}
	}

	inputFile.close(); // 关闭文件

	if (lines.empty()) { // 如果文件内容已被清空,则直接删除文件并返回
		std::remove(filename.c_str());
		std::cout << "文件已被清空。" << std::endl;
		return;
	}

	std::ofstream outputFile(filename); // 以写入模式打开同一个文件
	if (!outputFile) {
		std::cerr << "无法打开文件:" << filename << std::endl;
		return;
	}

	for (const auto& line : lines) {
		outputFile << line << std::endl; // 将修改后的内容写入文件
	}

	outputFile.close(); // 关闭文件

	std::cout << "学号为 " << student_id << " 的学生成绩信息已被删除。" << std::endl;
}

//文件内容查找函数
void FileContSearch(std::string name) {

	//cout << "函数被调用"<<endl;	//测试用例

	std::string filename = "./filename.txt";	//定义文件变量
	std::ifstream inputFile(filename); // 打开文件以读取内容

	std::string line;
	while (std::getline(inputFile, line)) {
		std::istringstream iss(line);
		std::string field2; // 第二个字段
		iss >> field2; // 读取第二个字段

		size_t pos = line.find(name); // 在整行中查找目标内容
		if (pos != std::string::npos) { // 如果找到匹配的内容,则输出整行内容
			std::cout << line << std::endl;

		}
	}

	inputFile.close(); // 关闭文件
}

//文件内容排序
void FileContSort(int m) {
	std::string filename = "./filename.txt"; // 定义文件名
	std::ifstream inputFile(filename);        // 打开文件进行读取
	std::vector<Student> students;            // 存储学生信息的结构体数组
	std::string line;

	while (std::getline(inputFile, line)) {
		std::istringstream iss(line);
		Student student;
		student.line = line;

		// 解析字段直到第m个字段
		for (int i = 1; i < m+4; ++i) {			//不要直接i<m!!!因为输入的m并不是i的边界值
			std::string temp;
			iss >> temp;
		}

		// 将第m个字段转换为整数作为分数
		iss >> student.score;

		students.push_back(student);
	}

	std::sort(students.begin(), students.end()); // 根据分数对学生进行排序

	for (const auto& student : students) {
		std::cout << student.line << std::endl; // 输出排好序的行内容
	}

	inputFile.close(); // 关闭文件
}

//统计函数
void FileContCount(int function_count) {
	std::string filename = "./filename.txt"; // 定义文件名
	std::ifstream inputFile(filename); // 打开文件以读取内容
	std::vector<Student_Beifen> students;
	std::string line;
	while (std::getline(inputFile, line)) {
		std::istringstream iss(line);
		std::vector<std::string> fields;
		std::string field;
		while (iss >> field) {
			fields.push_back(field);
		}

		int sum = 0;
		for (int i = fields.size() - 3; i < fields.size(); ++i) {
			sum += std::stoi(fields[i]);
		}
		double average = static_cast<double>(sum) / 3.0; // 计算平均数

		Student_Beifen student1;
		student1.line = line;
		student1.average = average;
		students.push_back(student1);
	}

	std::sort(students.begin(), students.end()); // 按平均数降序排列

	for (const auto& student1 : students) {
		std::cout << student1.line << " 平均分:" << student1.average << std::endl; // 输出按平均数降序的每行内容
	}

	inputFile.close(); // 关闭文件
}



//界面函数
void Interface() {
	int outputSelect = 0;	//控制功能列表选择变量
	int Class = 0;	//班级变量
	int state = 1;	//控制功能列表状态
	int state_class = 1;	//控制班级功能列表选择变量
	int outputSelect_class = 0;	//班级功能列表选择
	long long int student_id = 0;	//学号,并且以防学好超出int范围
	std::string name = "";	//学生姓名
	int source_sort = 0;	//排序选项
	int state_sort = 1;		//控制排序列表变量
	//string fname = "";		//班级文件名,用于区分班级
	int function_count = 0;		//控制统计功能的变量
	int state_count = 1;		//控制统计状态的变量

	while (state)
	{
		int state_count = 1;		//防止返回功能列表后无法再进行统计
		cout << "-------功能列表--------"<<endl;
		cout << "1、选择班级"<< endl;
		cout << "2、成绩查询"<<endl;
		cout << "3、成绩删除"<<endl;
		cout << "4、成绩统计"<<endl;
		cout << "5、成绩排序" << endl;
		cout << "6、退出程序"<<endl;
		cout << "选择你使用的功能:" ;
		cin >> outputSelect;
		switch (outputSelect) {
		case 1:
			std::cout << "\033[2J\033[1;1H"; // 清屏,并将光标移动到左上角

			cout << "---当前功能为班级选择---"<<endl;
			cout << "选择你的班级:";
			cin >> Class;
			cout << "";
			std::cout << "\033[2J\033[1;1H"; // 清屏,并将光标移动到左上角


			while (state_class) {	//进入班级功能选择


				cout << "---班级功能列表---" << endl;
				cout << "当前班级为:" << Class << "班" << endl;
				cout << "1、输入成绩" << endl;
				cout << "2、查看成绩" << endl;
				cout << "3、退至主功能列表" << endl;
				cout << "你的选择:";			
				cin >> outputSelect_class;	//这段代码要写入循环否则会产生死循环
				
				switch (outputSelect_class) {
				case 1:
					std::cout << "\033[2J\033[1;1H"; // 清屏,并将光标移动到左上角
					cout << "学号 姓名 性别 班级 数据结构 Linux 算法设计与分析 总分"<<endl;
					FileW();	//调用文件写入函数
					break;
				case 2:
					std::cout << "\033[2J\033[1;1H"; // 清屏,并将光标移动到左上角
					cout << "学号 姓名 性别 班级 数据结构 Linux 算法设计与分析 总分"<<endl;
					FileR();	//调用文件读取函数
					break;

				case 3:
					std::cout << "\033[2J\033[1;1H"; // 清屏,并将光标移动到左上角
					Interface();	//调用功能列表函数
					break;

				default:
					cout << "错误输入,退出程序";
					state_class = 0;
				}

			}
			break;

		case 2:
			std::cout << "\033[2J\033[1;1H"; // 清屏,并将光标移动到左上角
			cout << "你要查询的学生姓名:";
			cin >> name;
			FileContSearch(name);
			break;


		
		case 3:
			cout << "请输入你要删除成绩信息的学生学号:";
			cin >> student_id;
			FileContDel(student_id);	//调用成绩删除函数
			break;

		case 4:
			while (state_count) {
				cout << "1、统计每个学生的平均分,按平均分降序输出" << endl;
				cout << "2、统计每个班级的平均分,按平均分降序输出" << endl;	//功能未实现
				cout << "3、统计每个班中总分最高的前三名和总分最低的后三名" << endl;
				cout << "4、统计获得奖学金的学生信息(平均分>=90且各科成绩>=85)" << endl;
				cout << "5、返回功能列表" << endl;
				cout << "输入你选择的功能:";
				cin >> function_count;
				if (function_count == 5) {
					state_count = 0;
					std::cout << "\033[2J\033[1;1H"; // 清屏,并将光标移动到左上角
				}
				else {
					std::cout << "\033[2J\033[1;1H"; // 清屏,并将光标移动到左上角
					FileContCount(function_count);
				}
			}
			break;
		case 5:
			while (state_sort) {

				std::cout << "\033[2J\033[1;1H"; // 清屏,并将光标移动到左上角
				cout << "1、按照数据结构成绩降序" << endl;
				cout << "2、按照Linux编程成绩降序" << endl;
				cout << "3、按照算法设计与分析成绩降序" << endl;
				cout << "4、按照总分降序" << endl;
				cout << "请选择你的排序方式:";
				cin >> source_sort;
				if (source_sort == 1 || source_sort == 2 || source_sort == 3 || source_sort == 4) {

					FileContSort(source_sort);
				}
				else {
					cout << "输入有误,退出程序";
					std::exit(0); // 结束程序并返回状态码 0
				}
				cout << "0、返回功能列表" << endl;
				cout << "1、继续排序" << endl;
				cout << "请输入:";
				cin >> state_sort;
				std::cout << "\033[2J\033[1;1H"; // 清屏,并将光标移动到左上角

			}
			break;

		case 6:
			std::exit(0);	// 结束程序并返回状态码 0
			break;

		default:
			cout << "输入有误,退出程序";
			std::exit(0); // 结束程序并返回状态码 0
		}

	}
}

//折半插入排序函数
void binaryInsertionSort(int arr[], int n) {
	// 遍历数组
	for (int i = 1; i < n; i++) {
		// 获取当前元素
		int key = arr[i];
		// 定义二分查找的上下限
		int low = 0, high = i - 1;

		// 二分查找插入位置
		while (low <= high) {
			// 计算中间位置
			int mid = (low + high) / 2;
			// 如果当前元素小于中间位置的元素,则在左半侧继续查找插入位置
			if (key < arr[mid]) {
				high = mid - 1;
			}
			// 否则,在右半侧继续查找插入位置
			else {
				low = mid + 1;
			}
		}

		// 将大于当前元素的元素后移
		for (int j = i - 1; j >= low; j--) {
			arr[j + 1] = arr[j];
		}

		// 插入当前元素
		arr[low] = key;
	}
}



//冒泡排序函数
void bubbleSort(int arr[], int n) {
	// 外层循环控制每一轮比较的次数
	for (int i = 0; i < n - 1; i++) {
		// 内层循环进行相邻元素的比较和交换
		for (int j = 0; j < n - i - 1; j++) {
			// 如果前一个元素大于后一个元素,则交换它们的位置
			if (arr[j] > arr[j + 1]) {
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}

//快速排序函数
int partition(int arr[], int low, int high) {
	// 选择最后一个元素作为基准值
	int pivot = arr[high];
	// 初始化 i 为分区的边界索引,初始值为 low-1
	int i = low - 1;

	// 遍历分区内的元素
	for (int j = low; j <= high - 1; j++) {
		// 如果当前元素小于基准值,则将其交换到分区的边界位置,并更新边界索引
		if (arr[j] < pivot) {
			i++;
			swap(arr[i], arr[j]);
		}
	}

	// 将基准值交换到正确的位置上
	swap(arr[i + 1], arr[high]);
	// 返回基准值的索引
	return i + 1;
}

void quickSort(int arr[], int low, int high) {
	// 当分区的起始索引小于结束索引时进行递归排序
	if (low < high) {
		// 对分区进行划分,获取基准值的索引
		int pivotIndex = partition(arr, low, high);

		// 对左侧分区进行快速排序
		quickSort(arr, low, pivotIndex - 1);
		// 对右侧分区进行快速排序
		quickSort(arr, pivotIndex + 1, high);
	}
}


int main() {
	Interface();


	return 0;
}

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值