学校的课程设计
功能都实现了,因为懒,可能会有一些小问题,界面也没有怎么弄,如果你发现了程序有问题,请留言告诉我。
执行程序的密码是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