c++学生成绩管理系统

学校的课程设计

功能都实现了,因为懒,可能会有一些小问题,界面也没有怎么弄,如果你发现了程序有问题,请留言告诉我。

执行程序的密码是password, 其实可以弄一个TXT来存密码,但是太懒了,不想弄,就直接在代码那里弄了个变量来存密码。如果用TXT来存密码,就可以实现在程序执行时改密码。。。。

1.学生成绩管理系统
数据库的数据项主要数据包括:学号、姓名、年级、专业、成绩1、成绩2、成绩3、平均成绩、总成绩。
要求具有以下功能:
(1)添加、删除任意个记录。
(2)修改任意个记录。
(3)显示、保存记录。
(4)排序功能:打开学生数据库,计算每个学生的平均成绩和总成绩,用冒泡法或选择排序法将平均成绩和总成绩排序后生成两个新文件(从大到小),存盘并显示这两个文件的全部记录。
(5)查询功能:打开总成绩排序文件,用折半查找法统计出给定分数的人数并显示。
要求:
(1)设计一个主函数和多个子函数,每个子函数完成一个相对独立的子功能。
(2)程序运行时,首先进行口令检查,再显示菜单。并能根据菜单调用相应的函数功能。

口令程序段的功能要求:

  • 提示用户输入一个口令。
  • 用户输入口令后,若口令对,则提示用户通过,可执行后续程序;否则不通过。
  • 可对用户的口令输入进行次数限制(如:重复输入3次都不对),则自动退出系统。

(3)显示数据时,一页显示不下,可分页显示。

#include<iostream>
#include<string>
#include<fstream>
#include<iomanip>
#include<conio.h>
#include<windows.h>
#include<io.h>
using namespace std;

char buf[1024];//全局变量,用来存放跳过的行的内容,以便文件指针能到下一行开头 
int ending;
int bcount;

// //网上的定位函数
void gotoxy(int x, int y) {
	COORD pos = { x,y };
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
	SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}


//创建学生结构体
typedef struct student
{
	int num;//学号
	char name[10];//姓名
	int grade;//年级
	string subject;//专业
	int score[3];//成绩1,成绩2,成绩3
	float average;//平均成绩
	int sum;//总成绩	
	struct student* next;
}student, * ptrnode;


//获取文件总行数
int get_page(char file_name[])
{
	int status = _access(file_name, 0);
	int count;
	char buf[1024];
	if (status == -1)
	{
		ofstream outfile(file_name, ios::out);
		outfile << "num" << '\t' << "name" << '\t' << "grade" << '\t' << "subject" << '\t' << "score1" << '\t' << "score2" << '\t' << "score3" << '\t' << "sum" << '\t' << "average" << endl;
		outfile.close();
	}
	ifstream infile(file_name, ios::in);
	infile.seekg(0, ios::beg);
	infile.getline(buf, sizeof(buf));
	for (count = 0;!infile.eof();count++)
	{
		infile.getline(buf, sizeof(buf));

	}
	infile.close();

	count = count - 1;
	return (count);
}


//读取数据到内存
void read_data(ptrnode* head, char file_name[], int z = ending)
{
	/*
	结构体
	*/
	int i;

	(*head)->next = NULL;
	ptrnode p = new student;
	ifstream infile(file_name, ios::in);
	infile.getline(buf, sizeof(buf));//跳过第一行
	for (i = 0;i < z;i++)
	{
		p = new student;
		//infile >> p->num;
		infile >> p->num >> p->name >> p->grade >> p->subject >> p->score[0] >> p->score[1] >> p->score[2] >> p->sum >> p->average;
		p->next = (*head)->next;
		(*head)->next = p;
	}
	//p = head->next;

	infile.close();
	//delete p;


}

//计算总成绩和平均分
void account_data(ptrnode p)
{
	//计算总成绩

	p->sum = p->score[0] + p->score[1] + p->score[2];
	//计算平均分
	p->average = (float)(p->sum) / 3;
}


//添加数据
void add_data(ptrnode* head)
{
	string data[4];
	int record[5];
	int n, i = 0, k, temp;
	int sum, average;
	ptrnode p = new student;
	cout << "输入你要添加多少个学生信息:";
	cin >> n;

	if (n <= 0)
	{
		cout << "输入错误!";
		return;
	}
	while (i < n)
	{
		p = new student;
		cout << "输入你要添加的学号,姓名,年级,专业,成绩1,成绩2,成绩3" << endl;
		cin >> p->num >> p->name >> p->grade >> p->subject >> p->score[0] >> p->score[1] >> p->score[2];
		account_data(p);
		p->next = (*head)->next;
		(*head)->next = p;
		i++;
		ending++;
	}
	gotoxy(33, 13);
	cout << "添加成功!";
	system("pause");

}

//删除数据
void delete_data(ptrnode* head)
{
	ptrnode p;
	ptrnode p1 = new student;
	int status = 0;
	int answer;
	int empty_num;



	int i = 0;
	int n;
	cout << "输入你要删除多少个记录";
	cin >> n;
	while (i < n)
	{
		status = 0;
		p1 = (*head);
		p = new student;
		p = (*head)->next;
		cout << "输入你要删除的学生的学号" << endl;//选择学号的原因,学号是唯一的,但是姓名可能会同名
		cin >> empty_num;
		while (p != NULL)
		{
			if (p->num == empty_num)
			{
				cout << p->num << '\t' << p->name << '\t' << p->grade << '\t' << p->subject << '\t' << p->score[0] << '\t' << p->score[1] << '\t' << p->score[2] << '\t' << p->sum << '\t' << p->average << endl;
				cout << "是否是你想要删除的数据!  1.是  2.不是"<<endl;
				cin >> answer;
				if (answer == 1)
				{

					p1->next = p->next;

					status = 1;
					ending--;
					break;
				}
			}
			p1 = p1->next;
			p = p1->next;
		}
		if (status == 1)
		{
			cout << "删除成功" << endl;
		}
		else
			cout << "没有找到要删除的值" << endl;

		i++;
	}
	system("pause");

}


//修改数据
void modify_data(ptrnode* head)
{
	int status = 0, n, i = 0;
	char select;
	int answer;
	ptrnode p = new student;

	int student_num;
	cout << "输入你要修改多少个记录";
	cin >> n;
	while (i < n)
	{
		p = (*head)->next;
		cout << "输入你要修改学生信息的学号:";
		cin >> student_num;
		while (p != NULL)
		{
			if (p->num == student_num)
			{
				cout << p->num << '\t' << p->name << '\t' << p->grade << '\t' << p->subject << '\t' << p->score[0] << '\t' << p->score[1] << '\t' << p->score[2] << '\t' << p->sum << '\t' << p->average << endl;
				cout << "是否是你想要修改的数据!  1.是  2.不是" << endl;
				cin >> answer;
				if (answer == 1)
				{
					status = 1;
					cout << "输入你要修改的属性:" << endl << "1.num:" << p->num << endl
						<< "2.name:" << p->name << endl
						<< "3.grade:" << p->grade << endl
						<< "4.subject:" << p->subject << endl
						<< "5~~7:score1、score2、score3:" << p->score[0] << " " << p->score[1] << " " << p->score[2] << endl
						<< "8.退出程序 " << endl;
					cin >> select;
					switch (select)
					{
					case'1':cout << "你要修改为:";cin >> p->num;break;
					case'2':cout << "你要修改为:";cin >> p->name;break;
					case'3':cout << "你要修改为:";cin >> p->grade;break;
					case'4':cout << "你要修改为:";cin >> p->subject;break;
					case'5':cout << "你要修改为:";cin >> p->score[0];break;
					case'6':cout << "你要修改为:";cin >> p->score[1];break;
					case'7':cout << "你要修改为:";cin >> p->score[2];break;
					case'8':exit(666);
					default:cout << "输入错误,请重新输入";continue;
					}
					cout << "修改成功!" << endl;
				}
			}
			p = p->next;
		}
		if (status == 0)
		{
			cout << "没有找到你要修改学生的信息!";
		}
		i++;
	}
	system("pause");
}

//显示数据在黑框中(分页显示)

void show_data(ptrnode head)
{

	int count = 0;//用来计数   标记当前在链表中的第几个位置          0~4   5~9   10~14   15~19
	int page = 0;//用来记录当前是第几页
	//先打印第一页
	ptrnode p = new student;
	p = head->next;
	cout << "num" << '\t' << "name" << '\t' << "grade" << '\t' << "subject" << '\t' << "score1" << '\t' << "score2" << '\t' << "score3" << '\t' << "sum" << '\t' << "average" << endl;
	while (p != NULL && count < 5)
	{
		cout << p->num << '\t' << p->name << '\t' << p->grade << '\t' << p->subject << '\t' << p->score[0] << '\t' << p->score[1] << '\t' << p->score[2] << '\t' << p->sum << '\t' << p->average << endl;
		p = p->next;
		count++;
	}



	//要判断输出是否大于一页,如果不大于一页,没有分页显示功能,用ending来判断是否大于1页
	//5行为1页

	if (ending >= 5)
	{

		int i;

		char select;
		while (1)
		{
			cout << '\r' << "按1上一页,按2下一页,按3结束显示";
			select = _getch();
			switch (select)
			{
			case '1':
				if (page > 0)
				{
					system("cls");
					page--;
					p = head->next;
					//先让p指针循环到要打印的数据的开始的结点
					for (i = 0;i < (page * 5) - 1 && p != NULL;i++)
					{
						p = p->next;
					}
					cout << "num" << '\t' << "name" << '\t' << "grade" << '\t' << "subject" << '\t' << "score1" << '\t' << "score2" << '\t' << "score3" << '\t' << "sum" << '\t' << "average" << endl;
					for (i = 0;i < 5 && p != NULL;i++)
					{
						cout << p->num << '\t' << p->name << '\t' << p->grade << '\t' << p->subject << '\t' << p->score[0] << '\t' << p->score[1] << '\t' << p->score[2] << '\t' << p->sum << '\t' << p->average << endl;
						p = p->next;
					}

				}
				else
					cout << '\r';
				break;
			case '2':

				if (page < (ending / 5))
				{
					system("cls");
					page++;
					cout << "num" << '\t' << "name" << '\t' << "grade" << '\t' << "subject" << '\t' << "score1" << '\t' << "score2" << '\t' << "score3" << '\t' << "sum" << '\t' << "average" << endl;
					for (i = 0;i < 5 && p != NULL;i++)
					{
						cout << p->num << '\t' << p->name << '\t' << p->grade << '\t' << p->subject << '\t' << p->score[0] << '\t' << p->score[1] << '\t' << p->score[2] << '\t' << p->sum << '\t' << p->average << endl;
						p = p->next;
					}

				}
				break;
			case'3':return;
			default:break;
			}
		}
	}
	else
		cout << "无更多数据打印";
	system("pause");



}

//把结构体链表的数据存回文件中
void data_to_file(ptrnode head, char file_name[])
{

	ofstream outfile(file_name, ios::out);
	outfile.setf(ios::left);
	outfile << "num" << '\t' << "name" << '\t' << "grade" << '\t' << "subject" << '\t' << "score1" << '\t' << "score2" << '\t' << "score3" << '\t' << "sum" << '\t' << "average" << endl;
	ptrnode p = new student;
	p = head->next;
	while (p != NULL)
	{
		outfile << p->num << '\t' << p->name << '\t' << p->grade << '\t' << p->subject << '\t' << p->score[0] << '\t' << p->score[1] << '\t' << p->score[2] << '\t' << p->sum << '\t' << p->average << endl;
		p = p->next;
	}
	outfile.unsetf(ios::left);
	outfile.close();
	cout << "保存成功" << endl;
}


//排序
void maopao(ptrnode head)
{

	//平均成绩排序
	ofstream outfile("average_score.txt", ios::out);

	ptrnode p, q, tail, h;
	tail = NULL;
	h = head;
	while (h->next != tail)
	{
		p = head;
		q = p->next;
		while (q->next != tail)
		{
			if (p->next->average < q->next->average)
			{
				p->next = q->next;
				q->next = q->next->next;
				p->next->next = q;
				p = p->next;
			}
			else
			{
				p = p->next;
				q = q->next;

			}
		}
		tail = q;
	}
	char filename[] = "average_score.txt";
	//把结构体链表的数据存回文件中
	data_to_file(head, filename);

	//显示数据
	cout << "根据平均分排序的结果为:" << endl;
	show_data(head);




	//总成绩排序
	ofstream outfile1("sum_score", ios::out);
	tail = NULL;
	h = head;
	while (h->next != tail)
	{
		p = head;
		q = p->next;
		while (q->next != tail)
		{
			if (p->next->sum < q->next->sum)
			{
				p->next = q->next;
				q->next = q->next->next;
				p->next->next = q;
				p = p->next;
			}
			else
			{
				p = p->next;
				q = q->next;

			}
		}
		tail = q;
	}


	//把结构体链表的数据存回文件中
	char file_name[] = "sum_score.txt";
	data_to_file(head, file_name);

	//显示数据
	cout << "根据总分排序的结果为:" << endl;
	show_data(head);

	cout << "冒泡成功!";
	system("pause");


}



//查询功能

void check_data()
{
	/*
	按照给定的总成绩,存到check_data变量里

	*/
	char file_name[] = "sum_score.txt";

	int check_data;
	int status = _access("sum_score.txt", 0);//判断文件是否存在的函数 ,包含在<io.h>头文件中 具体使用方法:https://blog.csdn.net/hanxiucaolss/article/details/96114793

	if (status == -1)
	{
		gotoxy(32, 13);
		cout << "sum_score.txt文件不存在,请先进行冒泡排序" << endl;
		system("pause");
		return;

	}

	else
	{
		int score_sum[100];
		int n, i = 0;
		bcount = get_page(file_name);


		ptrnode p = new student;
		ptrnode p1 = new student;

		read_data(&p, file_name, bcount);

		p = p->next;
		for (i = 0;p != NULL;i++)
		{
			score_sum[i] = p->sum;
			p = p->next;
		}

		gotoxy(37, 11);        cout << "输入你要查找几个记录:";
		cin >> n;
		i = 0;
		while (i < n)
		{
			p1 = new student;
			system("cls");
			read_data(&p1, file_name, bcount);
			p1 = p1->next;
			int left = 0, right = 0, j = 0;
			int k = 0;
			int low = 1, high = bcount + 1, mid;
			gotoxy(37, 13);     cout << "输入你要查找的总成绩的值:";
			cin >> check_data;
			while (low <= high)
			{
				mid = (low + high) / 2;
				if (check_data < score_sum[mid])
				{
					high = mid - 1;
				}
				else if (check_data > score_sum[mid])
				{
					low = mid + 1;
				}
				else break;
			}
			for (j = mid;score_sum[j] == check_data && j >= 0;j--)//从找到的值往左遍历,如果与score_sum的值相等,则left++
			{
				left++;
			}
			for (j = mid + 1;score_sum[j] == check_data && j < bcount;j++)//从找到的值+1往右遍历,如果与score_sum的值相等,则right++
			{
				right++;
			}
			int a = j - left - right;
			while (p1 != NULL)
			{
				if (k >= a && k < j) {
					cout << p1->num << '\t' << p1->name << '\t' << p1->grade << '\t' << p1->subject << '\t' << p1->score[0] << '\t' << p1->score[1] << '\t' << p1->score[2] << '\t' << p1->sum << '\t' << p1->average << endl;
				}
				p1 = p1->next;
				k++;
			}
			cout << "一共找到" << left + right << "个人的总成绩符合查找值" << endl;
			system("pause");
			i++;
		}
	}

}




//打印菜单
void print_menu(ptrnode head)
{
	char  select1;
	char file_name[] = "student_system.txt";

	while (1)
	{
		system("cls");
		gotoxy(27, 7);cout << "选择功能:";
		gotoxy(37, 9);cout << "1.添加数据  " << '\t' << "2.删除数据";
		gotoxy(37, 11);cout << "3.修改数据  " << '\t' << "4.显示数据";
		gotoxy(37, 13);cout << "5.保存数据  " << '\t' << "6.冒泡排序";
		gotoxy(37, 15);cout << "7.查找总成绩  " << '\t' << "8.退出程序";
		gotoxy(45, 17);
		select1 = _getch();//选择添加、删除    、修改(通过链表定位到修改值)、查询(头链表循环查找)、打印所有的成绩(按链表中的page输出某一页)、排序(直接插入,冒泡)
		switch (select1)
		{
		case '1':system("cls");gotoxy(30, 5);add_data(&head);break;
		case '2':system("cls");delete_data(&head);break;
		case '3':system("cls");modify_data(&head);break;
		case '4':system("cls");show_data(head);system("pause");break;
		case '5':system("cls");data_to_file(head, file_name);system("pause");break;
		case '6':system("cls");maopao(head);break;
		case '7':system("cls");check_data();break;
		case '8':system("cls");exit(666);
		default:system("cls");break;
		}
	}
}


// 打印开始界面
void print_star(ptrnode head)
{
	int count = 3;
	string password;//初始密码设置为password
	while (count > 0)
	{
		gotoxy(34, 13);
		cout << "请输入密码,还剩输入次数" << count;
		gotoxy(40, 15);
		cin >> password;
		if (password == "password") break;
		count--;
		system("cls");

	}
	if (count <= 0)
	{
		gotoxy(32, 9);
		cout << "已达最大输入次数,即将退出程序!";
		system("pause");
		exit(666);
	}
	system("cls");
	//用到的头文件<windows.h>  <conio.h>       在黑框中某一位置打印
	char select;//不用INT类型的原因,如果是int类型,当用户输入aaa或则a的时候,程序出错

	gotoxy(38, 11);
	cout << "学生管理系统开始菜单";
	gotoxy(35, 15);
	cout << "1:进入系统   " << "2:退出程序";
	gotoxy(42, 17);

	select = _getch();
	switch (select)
	{
	case '1':system("cls");print_menu(head);break;
	case '2':exit(666);break;
	default:system("cls");print_star(head);
	}
	gotoxy(36, 17);
	//选择添加、删除    、修改(通过链表定位到修改值)、查询(头链表循环查找)、打印所有的成绩(按链表中的page输出某一页)、排序(直接插入,冒泡)


}


int main()
{
	system("mode con cols=100 lines=32");
	ptrnode head = new student;
	char file_name[] = "student_system.txt";
	ending = get_page(file_name);
	read_data(&head, file_name);
	ptrnode p = new student;
	p = head->next;
	print_star(head);
	delete head;

	return 0;
}


//历史错误
//https://bbs.csdn.net/topics/391077201
//https://blog.csdn.net/kestory/article/details/89737669
//int status = _access("student_system.txt", 0);//判断文件是否存在的函数 ,包含在<io.h>头文件中 具体使用方法:https://blog.csdn.net/hanxiucaolss/article/details/96114793
//判断文件是否存在的函数 ,包含在<io.h>头文件中 具体使用方法:https://blog.csdn.net/hanxiucaolss/
//要用二级指针https://bbs.csdn.net/topics/70168422


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值