/*3学生成绩管理
基本要求:
定义date类,至少包括年月日;
定义person类,至少包括姓名、性别、身份证号码和出生日期;
定义学生(student)类,从person类派生,至少包括学号、班级和四门功课的成绩。
功能要求:
1、设计菜单实现功能选择;
2、输入功能:输入学生信息,并保存到文件中;
3、计算每个学生的总分与平均分并排序
4、能根据学号修改学生信息
5、能根据学号删除学生信息
6、查询功能:
1)能够根据学号查询学生信息;
2)能够根据姓名、班级查询学生信息
3)统计学生成绩,按照班级和科目计算平均分。*/
#include<iostream>
#include<fstream>
#include<typeinfo>
#include<math.h>
using namespace std;
int Z = 0;//内存学生数
class date
{
public:
string year;
string month;
string day;
};
class person
{
protected:
string name;
string sex;
string idnum;
date birth;
public:
person() {}
~person() {}
};
class student :public person
{
private:
string stunum;
string classnum;
string grade[4];
public:
string gstunum()
{
return stunum;
}
string gclassnum()
{
return classnum;
}
string gname()
{
return name;
}
string ggrade(int i)
{
return grade[i];
}
string gsex()
{
return sex;
}
void snum(string num)
{
stunum = num;
}
friend istream& operator >>(istream& is, student& ra);
friend ostream& operator <<(ostream& os, student& ra);
};
void map(student);
void shuru(student);
void baocun(student);
void duqu(student);
void chaxun(student);
void paixu(student);
int str_int(string);
void chakan(student);
void shangchu(student);
void xiugai(student);
void banjipaiming(student);
istream& operator >>(istream& is, student& ra)
{
if (typeid(is) == typeid(cin))
{
cout << "学号" << endl;
is >> ra.stunum;
cout << "班级" << endl;
is >> ra.classnum;
cout << "姓名" << endl;
is >> ra.name;
cout << "身份证号" << endl;
is >> ra.idnum;
cout << "性别" << endl;
is >> ra.sex;
cout << "生日年" << endl;
is >> ra.birth.year;
cout << "生日月" << endl;
is >> ra.birth.month;
cout << "生日日" << endl;
is >> ra.birth.day;
cout << "成绩" << endl;
for (int i = 0; i < 4; i++) {
is >> ra.grade[i];
}
}
else
{
is >> ra.stunum >> ra.classnum >> ra.name >> ra.idnum >> ra.sex >> ra.birth.year >> ra.birth.month >> ra.birth.day;
for (int i = 0; i < 4; i++)
{
is >> ra.grade[i];
}
}
return is;
}
ostream& operator <<(ostream& os, student& ra)
{
if (typeid(os) == typeid(cout))
{
os << "学号 " << ra.stunum << " ";
os << "班级 " << ra.classnum << " ";
os << "姓名 " << ra.name << " ";
os << "身份证号 " << ra.idnum << " ";
os << "性别 " << ra.sex << " ";
os << "生日年 " << ra.birth.year << " ";
os << "生日月 " << ra.birth.month << " ";
os << "生日日 " << ra.birth.day << " ";
os << "成绩 " << " ";
for (int i = 0; i < 4; i++) {
os << ra.grade[i] << " ";
}
os << endl;
}
else
{
os << ra.stunum << " " << ra.classnum << " " << ra.name << " " << ra.idnum << " " << ra.sex << " " << ra.birth.year << " " << ra.birth.month << " " << ra.birth.day;
for (int i = 0; i < 4; i++)
{
os << " " << ra.grade[i] << " ";
}
os << endl;
}
return os;
}
void shuru(student stu[])
{
cin >> stu[Z];
Z++;
cout << "输入成功" << endl;
system("pause");
}
void baocun(student stu[])
{
ofstream ofs;
ofs.open("d:\\student.txt");
int a = Z;
for (int i = 0; i < a; i++)
{
ofs << stu[i];
Z--;
}
ofs.close();
cout << "保存完成" << endl;
system("pause");
}
void duqu(student stu[])
{
ifstream ifs;
ifs.open("d:\\student.txt");
while (!ifs.eof())
{
ifs >> stu[Z];
Z++;
}
Z--;
ifs.close();
cout << "读取完成" << endl;
system("pause");
}
void chaxun(student stu[])
{
cout << "请输入学生学号或姓名和班级" << endl;
string sign;
cin >> sign;
for (int i = 0; i < Z; i++)
{
if (sign == stu[i].gstunum() || sign == (stu[i].gclassnum() + stu[i].gname()) || sign == (stu[i].gname() + stu[i].gclassnum()))
{
cout << stu[i];
system("pause");
}
}
}
void paixu(student stu[])
{
int mark[100] = { 0 };//学生总成绩
int paiming[100] = { 0 };//学生排名
int max = -999999;
int maxpos = -1;
int pingjunfen[100];
for (int i = 0; i < Z; i++)
{
for (int j = 0; j < 4; j++)
{
mark[i] += str_int(stu[i].ggrade(j));
}
pingjunfen[i] = mark[i] / 4;
}
for (int i = 0; i < Z; i++)
{
for (int j = 0; j < Z; j++)
{
if (mark[j] >= max)
{
max = mark[j];
maxpos = j;
}
}
max = -999999;
mark[maxpos] = -99999999;
paiming[i] = maxpos;
}
cout << "名次" << " 学号" << " 班级" << " 姓名" << " 总分" << " 平均分" << endl;
for (int i = 0; i < Z; i++)
{
cout << "第" << i + 1 << "名 " << stu[paiming[i]].gstunum() << " " << stu[paiming[i]].gclassnum() << " " << stu[paiming[i]].gname() << " " << pingjunfen[paiming[i]] * 4 << " " << pingjunfen[paiming[i]] << endl;
}
system("pause");
}
int str_int(string s)
{
int sl = s.size();
char Int[10];
int wei = 0;
int ans = 0;
for (int i = 0; i < sl; i++)
{
wei++;
Int[i] = s[i];
}
for (int i = 0; i < sl; i++)
{
if (wei != 0)
{
ans = ans + (Int[i] - '0') * pow(10, wei - 1);
wei--;
}
}
return ans;
}
void chakan(student stu[])
{
for (int i = 0; i < Z; i++)
{
cout << stu[i];
}
system("pause");
}
void shangchu(student stu[])
{
cout << "请输入需要删除的学号" << endl;
string num;
cin >> num;
int Intnum = str_int(num);
if (Intnum == 1)
{
for (int i = Z - 1; i >= 1; i--)
{
stu[i].snum(stu[i - 1].gstunum());
}
for (int i = 0; i < Z; i++)
{
stu[i] = stu[i + 1];
}
Z--;
cout << "删除成功" << endl;
system("pause");
}
else if (Intnum == Z)
{
Z--;
cout << "删除成功" << endl;
system("pause");
}
else
{
for (int i = Z - 1; i >= Intnum - 1; i--)
{
stu[i].snum(stu[i - 1].gstunum());
}
for (int i = Intnum - 1; i < Z; i++)
{
stu[i] = stu[i + 1];
}
Z--;
cout << "删除成功" << endl;
system("pause");
}
}
void xiugai(student stu[])
{
cout << "请输入要修改的学生学号" << endl;
int chose;
cin >> chose;
cout << stu[chose];
cout << "请输入要修改的内容" << endl;
cin >> stu[chose];
}
void banjipaiming(student stu[])
{
int banji[100] = { 0 };//班级人数
int classmark[100] = { 0 };//班级总分
int men[100] = { 0 };//班级男生人数
int women[100] = { 0 };//班级女生人数
int classzongpaiming[100] = { 0 };//班级总成绩排名
int classpingpaiming[100] = { 0 };//班级总成绩排名
int classpingjun[100] = { 0 };//班级平均分
int pingjuntemp[100] = { 0 };//平均分暂时存放的地方
int zongtemp[100] = { 0 };//总分暂时存放的地方
int classmax = -9999999;//最高分
int classmaxpos = -1; //最高分位置
int banjinum = 0;//班级数
for (int i = 0; i < Z; i++)//i为学生序号
{
for (int j = 1; j < 11; j++)//j为班级序号
{
if (str_int(stu[i].gclassnum()) == (-1260 + (j - 1) * 100))//如果学生班级号等于j
{
banji[j]++;
if (stu[i].gsex() == "男")
{
men[j] ++;
}
else
{
women[j]++;
}
for (int k = 0; k < 4; k++)//k为四门成绩序号
{
classmark[j] += str_int(stu[i].ggrade(k));
zongtemp[j] += str_int(stu[i].ggrade(k));
}
}
}
}
for (int i = 1; i < 11; i++)
{
if (banji[i] != 0)//班级人数不等于0
{
banjinum++;
}
}
for (int j = 1; j <= banjinum; j++)//j为班级序号
{
if (banji[j] != 0)
{
classpingjun[j] = classmark[j] / banji[j];
pingjuntemp[j] = classmark[j] / banji[j];
}
}
for (int i = 1; i <= banjinum; i++)//排名,名次
{
for (int j = 1; j <= banjinum; j++)//j为班级号
{
if (classmark[j] >= classmax)
{
classmax = classmark[j];
classmaxpos = j; //j为班级号
}
}
classmax = -999999;
classmark[classmaxpos] = -99999999;
classzongpaiming[i] = classmaxpos;//名次为i的班级号
}
for (int i = 1; i <= banjinum; i++)//排名,名次
{
for (int j = 1; j <= banjinum; j++)//j为班级号
{
if (classpingjun[j] >= classmax)
{
classmax = classpingjun[j];
classmaxpos = j; //j为班级号
}
}
classmax = -999999;
classpingjun[classmaxpos] = -99999999;
classpingpaiming[i] = classmaxpos;//名次为i的班级号
}
cout << "请输入需要查看的信息" << endl;
cout << "1-----班级总分排名" << endl;
cout << "2-----班级平均分分排名" << endl;
cout << "3-----各班级信息" << endl;//人数,男女数量,总成绩排名
int chose;
cin >> chose;
switch (chose)
{
case 1:
cout << " 班级总分排名" << endl;
for (int i = 1; i <= banjinum; i++)
{
cout << " 第 " << i << " 名 " << classzongpaiming[i] << "班" << " 总分 " << zongtemp[classzongpaiming[i]] << endl;
}
break;
case 2:
cout << " 班级平均分排名" << endl;
for (int i = 1; i <= banjinum; i++)
{
cout << " 第 " << i << " 名 " << classpingpaiming[i] << "班" << " 平均分 " << pingjuntemp[classpingpaiming[i]] << endl;
}
break;
case 3:
cout << " 各班级信息" << endl;
cout << "班级" << " 人数" << " 男 " << " 女 " << " 总分" << " 平均分" << endl;
for (int i = 1; i <= banjinum; i++)
{
cout << i << "班 " << banji[i] << " " << men[i] << " " << women[i] << " " << zongtemp[i] << " " << pingjuntemp[i] << endl;
}
break;
}
system("pause");
}
void map(student stu[])
{
int state = 1;
while (1)
{
cout << " ***************************** 学生成绩管理系统************************************" << endl;
cout << " *****************************1-- 输入学生信息*************************************" << endl;
cout << " *****************************2-- 保存学生信息*************************************" << endl;
cout << " *****************************3-- 读取学生信息*************************************" << endl;
cout << " *****************************4-- 查询学生信息*************************************" << endl;
cout << " *****************************5-- 查看学生排名*************************************" << endl;
cout << " *****************************6-- 修改学生信息*************************************" << endl;
cout << " *****************************7-- 删除学生信息*************************************" << endl;
cout << " *****************************8-- 查看学生信息*************************************" << endl;
cout << " *****************************9-- 查看各班信息*************************************" << endl;
cout << " *****************************10-- 退出 *************************************" << endl;
int chose;
cout << endl << " --------------请输入选择的操作---------------- " << endl;
cin >> chose;
switch (chose)
{
case 1:shuru(stu); break;
case 2:baocun(stu); break;
case 3:duqu(stu); break;
case 4:chaxun(stu); break;
case 5:paixu(stu); break;
case 6:xiugai(stu); break;
case 7:shangchu(stu); break;
case 8:chakan(stu); break;
case 9:banjipaiming(stu); break;
case 10:state = 0; break;
}
system("cls");
if (state == 0)
{
break;
}
}
}
int main()
{
student* p;
p = new student[100];
map(p);
delete[]p;
return 0;
}
// 学生管理系统.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "string.h"
#include "conio.h"
#include "windows.h"
#include "stdlib.h"
#define LIST_TITLE "学号 姓名 性别 语文 数学 英语\n"
#define LIST_TITLE_1 "学号 姓名 性别 语文 数学 英语 均分\n"
#define FILE_DATABASE "C:\student_database.dat"
#define FILE_EXPORT "C:\student_export.txt"
//颜色
enum
{
BLACK,
BLUE,
GREEN,
CYAN,
RED,
MAGENTA,
BROWN,
LIGHTGRAY,
DARKGRAY,
LIGHTBLUE,
LIGHTGREEN,
LIGHTCYAN,
LIGHTRED,
LIGHTMAGENTA,
YELLOW,
WHITE
};
//功能索引
enum
{
Func_Add = 1,//添加学生信息
Func_Delete,//删除
Func_Modify,//修改
Func_Search,//搜索
Func_Sort,//排序
Func_Save,//保存
Func_AutoSave,//自动保存
Func_Vote,//投票系统
Func_Export,//导出学生信息
Func_ExitSystem//退出系统
};
struct Student
{
int num;//学号
char name[20];//姓名
char sex[8];//性别
float score[3];//三门课程成绩
float averge;//平均分
int count;//投票计数
Student* pNext;
};
Student* G_pStuHead;//链表头
bool G_autoStore = false;//自动保存
//
/设置字体颜色/
//
void setFontColor(int ForgC)
{
WORD wColor;
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
if(GetConsoleScreenBufferInfo(hOutput, &csbi))
{
//设置字体颜色
wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);
SetConsoleTextAttribute(hOutput, wColor);
}
}
//
/光标跳转到指定位置/
//
void gotoxy(int x, int y)
{
// 更新光标位置
COORD pos;
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(hOutput, pos);
// 隐藏光标
// CONSOLE_CURSOR_INFO cursor;
// cursor.bVisible = FALSE;
// cursor.dwSize = 1; //值介于1 ~ 100 之间 单元格底部为下划线 ~ 完全填充单元格
// SetConsoleCursorInfo(hOutput, &cursor);
}
//
/主菜单中指定位置打印是否自动保存/
//
void printAutoStoreInfo()
{
setFontColor(LIGHTGREEN);
gotoxy(13, 10);
printf("%s\n", G_autoStore ? "是" : "否");
setFontColor(WHITE);
}
//
/显示最上面的系统标题/
//
void showSystemTitle()
{
setFontColor(LIGHTGREEN);
printf("--------------------------------------------------------\n");
printf("\t\t欢迎进入学生管理系统\n");
printf("--------------------------------------------------------\n");
setFontColor(WHITE);
}
//
/初始化屏幕/
//
void initScreen()
{
system("CLS");
showSystemTitle();
printf("请输入数字序列号,选择您要执行的操作:\n");
printf("1、添加学生信息\n");
printf("2、删除学生信息\n");
printf("3、修改学生信息\n");
printf("4、查询学生信息\n");
printf("5、排序\n");
printf("6、保存(如打开自动保存,则无需手动执行)\n");
printf("7、自动保存:");
printAutoStoreInfo();
printf("8、投票系统\n");
printf("9、导出学生信息\n");
setFontColor(LIGHTRED);
printf("10、退出学生管理系统\n");
setFontColor(WHITE);
}
//
/从指定位置开始清除指定长度元素/
//
void gotodelete(int x, int y, int length)
{
int i;
for (i = 0; i < length; i++)
{
gotoxy(x + i, y);
printf(" ");
}
}
//
/清除指定位置元素/
//
void gotodelete(int x, int y)
{
gotodelete(x, y, 1);
}
//
/投票系统 /
//
void voteSystem()
{
bool hasFound;
char name[20];
int count, i, j;
Student* pStu, *pTmp;
Student pStuArr;
//初始化票数清零
pStu = G_pStuHead->pNext;
while(pStu != NULL)
{
pStu->count = 0;
pStu = pStu->pNext;
}
count = 0;
pStuArr = (Student**)malloc(4 * 100);//用于存放已经获得票数的同学指针
gotoxy(0, 6);
printf("投票结果如下:\n");
gotoxy(0, 3);
printf("请在下方输入你想投给的人的姓名(输入-1返回主菜单):\n");
while (1)
{
gotodelete(0, 4, 20);//清空输入行
gotoxy(0, 4);
scanf("%s", name);
if(strcmp(name, "-1") == 0)
{
break;
}
hasFound = false;
pStu = G_pStuHead->pNext;
//在系统中查找对应的人名
while(pStu != NULL)
{
if(strcmp(pStu->name, name) == 0)
{
hasFound = true;
break;
}
pStu = pStu->pNext;
}
if(! hasFound)
{
printf("查无此人!!!");
Sleep(1000);
gotodelete(0, 5, 20);
continue;
}
//找到之后,这个人所对应的票数+1
pStu->count++;
for (i = 0; i < count; i++)
{
if(pStuArr[i] == pStu)
{
break;
}
}
if(i == count)//说明未找到,则添加进候选人数组
{
pStuArr[count++] = pStu;
if(count % 100 == 0)
{
pStuArr = (Student**)realloc(pStuArr, count + 100);
}
}
//冒泡排序,票数
for (i = 0; i < count - 1; i++)
{
for (j = i + 1; j < count; j++)
{
if(pStuArr[i]->count < pStuArr[j]->count)
{
pTmp = pStuArr[i];
pStuArr[i] = pStuArr[j];
pStuArr[j] = pTmp;
}
}
}
gotoxy(0, 7);//跳转到打印票数的那行
//打印票数
for (i = 0; i < count; i++)
{
if(i == 0)
{
setFontColor(LIGHTGREEN);
}
else
{
setFontColor(WHITE);
}
printf("%d %s\t%d\n", pStuArr[i]->num, pStuArr[i]->name, pStuArr[i]->count);
}
}
free(pStuArr);
}
//
/导出学生信息(明文) /
//
bool exportStudentInfo()
{
Student pStu;
FILE fp;
pStu = G_pStuHead->pNext;
if((fp = fopen(FILE_EXPORT, "w")) == NULL)
{
return false;
}
while (pStu != NULL)
{
fprintf(fp, "%d %s %s %.2f %.2f %.2f %.2f\n", pStu->num, pStu->name, pStu->sex,
pStu->score[0], pStu->score[1], pStu->score[2], pStu->averge);
pStu = pStu->pNext;
}
fclose(fp);
return true;
}
/********************************************************************/
/保存学生信息 (以数据库形式保存)/
/********************************************************************/
bool saveStudentInfo()
{
FILE *fp;
Student *pStu;
pStu = G_pStuHead;
if((fp = fopen(FILE_DATABASE, "wb")) == NULL)
{
return false;
}
fwrite(&G_autoStore, sizeof(G_autoStore), 1, fp);
while (pStu != NULL)
{
fwrite(pStu, sizeof(Student), 1, fp);
pStu = pStu->pNext;
}
fclose(fp);
return true;
}
/************************************************************************/
/读取学生信息(读取数据库形式的文档) /
/**********************************************************************/
bool loadStudentInfo()
{
FILE *fp;
int count;
Student stu, *pStu, *pStuNew;
count = 0;
pStu = G_pStuHead;
if((fp = fopen(FILE_DATABASE, "rb")) == NULL)
{
return false;
}
fread(&G_autoStore, sizeof(G_autoStore), 1, fp);//读取是否自动保存
while(1)
{
fread(&stu, sizeof(Student), 1, fp);//读取文档中每个同学的数据
if(feof(fp))//到文档尾则跳出
{
break;
}
if(count++ > 0)//这里 > 0 是因为保存的时候会把链表头保存进去,而链表头是没有有效数据的,所以要排除掉
{
pStuNew = (Student*)malloc(sizeof(Student));
MoveMemory(pStuNew, &stu, sizeof(Student) - 4);//将结构体除指针外的所有数据拷贝进内存
pStuNew->pNext = NULL;
pStu->pNext = pStuNew;
pStu = pStuNew;
}
if(stu.pNext == NULL)
{
break;
}
}
fclose(fp);
return true;
}
/************************************************************************/
/学生信息排序 /
/**********************************************************************/
bool sortStudentInfo()
{
int order1, order2;
bool swapData;
char yesOrNo;
Student* pStu1, *pStu2, tmpStu;
pStu1 = G_pStuHead->pNext;
if(pStu1 == NULL)
{
printf("系统中无学生信息!\n");
system("pause");
return false;
}
printf("输入以下序号执行相应功能(输入其他序号返回主菜单):\n");
printf("1、根据学号进行排序\n");
printf("2、根据姓名排序\n");
printf("3、根据语文成绩排序\n");
printf("4、根据数学成绩排序\n");
printf("5、根据英语成绩排序\n");
printf("6、根据平均分成绩排序\n");
scanf("%d", &order1);
if(order1 >= 1 && order1 <= 6)
{
printf("请选择正序OR倒序排列?(输入其他序号返回主菜单)\n");
printf("1、正序排列\n");
printf("2、倒序排列\n");
scanf("%d", &order2);
if(order2 >= 1 && order2 <= 2)
{
//冒泡排序
for ( ; pStu1->pNext != NULL; pStu1 = pStu1->pNext)
{
for (pStu2 = pStu1->pNext; pStu2 != NULL; pStu2 = pStu2->pNext)
{
swapData = false;//是否交换数据
switch(order1)
{
case 1://根据学号排序
{
if(order2 == 1 ? (pStu1->num > pStu2->num) : (pStu1->num < pStu2->num))//三目运算符, 判断正序还是倒序
{
swapData = true;
}
break;
}
case 2://根据姓名排序
{
if(order2 == 1 ? (strcmp(pStu1->name, pStu2->name) > 0) : (strcmp(pStu1->name, pStu2->name) < 0))
{
swapData = true;
}
break;
}
case 3://根据语文排序
case 4://根据数学排序
case 5://根据英语排序
{
if(order2 == 1 ? (pStu1->score[order1 - 3] > pStu2->score[order1 - 3]) : (pStu1->score[order1 - 3] < pStu2->score[order1 - 3]))
{
swapData = true;
}
break;
}
case 6://根据均分排序
{
if(order2 == 1 ? (pStu1->averge > pStu2->averge) : (pStu1->averge < pStu2->averge))
{
swapData = true;
}
break;
}
}
if(swapData)
{
//交换内存数据,只需要将除pNext指针外的结构体数据拷贝交换即可
MoveMemory(&tmpStu, pStu1, sizeof(Student) - 4);
MoveMemory(pStu1, pStu2, sizeof(Student) - 4);
MoveMemory(pStu2, &tmpStu, sizeof(Student) - 4);
}
}
}
printf("排序完成,是否显示?Y/N\n");
getchar();//过滤掉输入时的换行符
scanf("%c", &yesOrNo);
if(yesOrNo == 'Y' || yesOrNo == 'y')
{
pStu1 = G_pStuHead->pNext;
setFontColor(LIGHTGREEN);
printf(LIST_TITLE_1);//显示列表标题头
setFontColor(WHITE);
//打印排序后的各个学生信息
while(pStu1 != NULL)
{
printf("%d %s %s %.2f %.2f %.2f %.2f\n", pStu1->num, pStu1->name, pStu1->sex,
pStu1->score[0], pStu1->score[1], pStu1->score[2], pStu1->averge);
pStu1 = pStu1->pNext;
}
system("pause");
}
return true;
}
}
return false;
}
//
/查询学生信息 /
//
void searchStudentInfo()
{
bool hasFound;
int order, stuID, count, i, min, max;
float score;
char name[20];
Student pStu;
Student* pStuArr;
pStuArr = NULL;
while (1)
{
system("CLS");
showSystemTitle();
if(pStuArr != NULL)//如果再次查询,这里需要判断,将上一轮查询的学生信息指针数组清空
{
free(pStuArr);
}
count = 0;
stuID = 0;
hasFound = false;
pStu = G_pStuHead->pNext;
pStuArr = (Student**)malloc(4 * 100);//初始化查询到后存放的学生信息指针数组
printf("输入以下序号执行相应功能(输入其他序号返回主菜单):\n");
printf("1、输入学号查询信息\n");
printf("2、输入姓名查询信息\n");
printf("3、输入语文成绩范围查询信息\n");
printf("4、输入数学成绩范围查询信息\n");
printf("5、输入英语成绩范围查询信息\n");
printf("6、输入平均分范围查询信息\n");
printf("7、列出所有学生信息\n");
scanf("%d", &order);
switch(order)
{
case 1://根据学号查询
{
printf("请输入要查询的学生学号:");
scanf("%d", &stuID);
while (pStu != NULL)
{
if(pStu->num == stuID)
{
hasFound = true;
break;
}
pStu = pStu->pNext;
}
if(hasFound)//
{
setFontColor(LIGHTGREEN);
printf(LIST_TITLE_1);
setFontColor(WHITE);
printf("%d %s %s %.2f %.2f %.2f %.2f\n", pStu->num, pStu->name, pStu->sex,
pStu->score[0], pStu->score[1], pStu->score[2], pStu->averge);
}
break;
}
case 2://根据姓名查询
{
printf("请输入要查询的学生姓名:");
scanf("%s", name);
while (pStu != NULL)
{
if(strcmp(pStu->name, name) == 0)
{
hasFound = true;
pStuArr[count++] = pStu;
if(count % 100 == 0)
{
pStuArr = (Student**)realloc(pStuArr, count + 100);
}
}
pStu = pStu->pNext;
}
if(hasFound)
{
setFontColor(LIGHTGREEN);
printf(LIST_TITLE_1);
setFontColor(WHITE);
for (i = 0; i < count; i++)
{
printf("%d %s %s %.2f %.2f %.2f %.2f\n", pStuArr[i]->num, pStuArr[i]->name, pStuArr[i]->sex,
pStuArr[i]->score[0], pStuArr[i]->score[1], pStuArr[i]->score[2], pStuArr[i]->averge);
}
}
break;
}
case 3://根据语文成绩范围查询
case 4://根据数学成绩范围查询
case 5://根据英语成绩范围查询
case 6://根据平均分范围查询
{
char *subjectStrArr[4] = {"语文", "数学", "英语", "平均"};
printf("请输入要查询的%s成绩范围:", subjectStrArr[order - 3]);
scanf("%d %d", &min, &max);
while (pStu != NULL)
{
if(order < 6)// 3 ~ 5
{
score = pStu->score[order - 3];
}
else //order = 6
{
score = pStu->averge;
}
if(score >= min && score <= max)
{
//找到符合条件的学生信息,则加入到指针数组中去
hasFound = true;
pStuArr[count++] = pStu;
if(count % 100 == 0)
{
pStuArr = (Student**)realloc(pStuArr, count + 100);
}
}
pStu = pStu->pNext;
}
if(hasFound)
{
setFontColor(LIGHTGREEN);
printf(LIST_TITLE_1);
setFontColor(WHITE);
//打印指针数组中的学生信息
for (i = 0; i < count; i++)
{
printf("%d %s %s %.2f %.2f %.2f %.2f\n", pStuArr[i]->num, pStuArr[i]->name, pStuArr[i]->sex,
pStuArr[i]->score[0], pStuArr[i]->score[1], pStuArr[i]->score[2], pStuArr[i]->averge);
}
}
break;
}
case 7://列出所有学生信息
{
hasFound = true;
setFontColor(LIGHTGREEN);
printf(LIST_TITLE_1);
setFontColor(WHITE);
while(pStu != NULL)
{
printf("%d %s %s %.2f %.2f %.2f %.2f\n", pStu->num, pStu->name, pStu->sex,
pStu->score[0], pStu->score[1], pStu->score[2], pStu->averge);
pStu = pStu->pNext;
}
break;
}
default:
{
goto lab_search;
}
}
if(! hasFound)
{
printf("未能找到相应的学生信息!\n");
}
system("pause");
}
lab_search:
free(pStuArr);
}
/************************************************************************/
/删除学生信息 /
/**********************************************************************/
bool deleteStudentInfo()
{
char yesOrNo;
int stuID;
bool hasFound;
Student* pStu, *pStu1;
hasFound = false;
pStu = G_pStuHead->pNext;
pStu1 = G_pStuHead;
printf("请输入欲删除的学生学号:");
scanf("%d", &stuID);
while (pStu != NULL)
{
if(pStu->num == stuID)
{
hasFound = true;
break;
}
pStu1 = pStu;
pStu = pStu->pNext;
}
if(hasFound)
{
printf("找到此学生的信息如下:\n");
setFontColor(LIGHTGREEN);
printf(LIST_TITLE_1);
setFontColor(WHITE);
printf("%d %s %s %.2f %.2f %.2f %.2f\n", pStu->num, pStu->name, pStu->sex,
pStu->score[0], pStu->score[1], pStu->score[2], pStu->averge);
printf("是否删除?Y/N");
getchar();//过滤掉输入时的换行符
scanf("%c", &yesOrNo);
if(yesOrNo == 'y' || yesOrNo == 'Y')
{
pStu1->pNext = pStu->pNext;
free(pStu);
printf("已删除\n");
}
else
{
hasFound = false;
}
}
else
{
printf("未找到对应学生的信息\n");
}
system("pause");
return hasFound;
}
//
/修改学生信息 /
//
bool modifyStudentInfo()
{
int order, count, i;
int stuID;
char name[20];
char yesOrNo;
bool hasModify;
Student pStu;
Student* pStuArr;
hasModify = false;
count = 0;
pStu = G_pStuHead->pNext;
pStuArr = (Student**)malloc(4 * 100);//用于存放查找到的学生信息指针,这里定义指针数组是防止查询姓名出现重名
printf("请输入以下序号,选择对应功能(1或2,否则返回上级菜单)\n");
printf("1、输入学号查找学生\n");
printf("2、输入姓名查找学生\n");
scanf("%d", &order);
if(order == 1)
{
printf("请输入要修改的学生学号:\n");
scanf("%d", &stuID);
while(pStu != NULL)
{
if(pStu->num == stuID)
{
pStuArr[count++] = pStu;
break;
}
pStu = pStu->pNext;
}
}
else if(order == 2)
{
printf("请输入要修改的学生姓名:\n");
scanf("%s", name);
while(pStu != NULL)
{
if(strcmp(pStu->name, name) == 0)
{
pStuArr[count++] = pStu;
if(count % 100 == 0)//如果数组存放满了,则再次申请内存
{
pStuArr = (Student**)realloc(pStuArr, count + 100);
}
}
pStu = pStu->pNext;
}
}
else
{
return false;
}
if(count == 0)
{
printf("未能找到任何信息,是否继续修改?Y/N");
getchar();//过滤掉输入时的换行符
scanf("%c", &yesOrNo);
if(yesOrNo == 'y' || yesOrNo == 'Y')
{
system("CLS");
showSystemTitle();
return modifyStudentInfo();
}
}
else
{
printf("为您查找到%d个学生信息:\n ", count);
setFontColor(LIGHTGREEN);
printf(LIST_TITLE);
setFontColor(WHITE);
for (i = 0; i < count; i++)
{
printf("%d、%d %s %s %.2f %.2f %.2f\n", i + 1, pStuArr[i]->num, pStuArr[i]->name, pStuArr[i]->sex,
pStuArr[i]->score[0], pStuArr[i]->score[1], pStuArr[i]->score[2]);
}
printf("请输入您要修改的信息序号(1~%d),其他数字返回主菜单\n", count);
scanf("%d", &order);
if(order >= 1 && order <= count)
{
printf("请依次输入\n");
setFontColor(LIGHTGREEN);
printf(LIST_TITLE);
setFontColor(WHITE);
pStu = pStuArr[order - 1];
scanf("%d %s %s %f %f %f", &pStu->num, pStu->name, pStu->sex, &pStu->score[0], &pStu->score[1], &pStu->score[2]);
pStu->averge = (pStu->score[0] + pStu->score[1] + pStu->score[2]) / 3;
hasModify = true;
}
}
free(pStuArr);
return hasModify;
}
//
/检测学号是否存在/
//
bool checkStuIDExist(int stuID)
{
Student* pStu;
pStu = G_pStuHead->pNext;
while(pStu != NULL)
{
if(pStu->num == stuID)
{
return true;
}
pStu = pStu->pNext;
}
return false;
}
/************************************************************************/
/添加学生信息 /
/**********************************************************************/
bool addStudentInfo()
{
printf("输入-1回车,返回上级菜单\n");
setFontColor(LIGHTGREEN);
printf(LIST_TITLE);
setFontColor(WHITE);
char c;
bool hasAdd = false;
Student* pStu = G_pStuHead;
Student* pStuNew;
while (pStu->pNext != NULL)
{
pStu = pStu->pNext;
}
while(1)
{
pStuNew = (Student*)malloc(sizeof(Student));
scanf("%d", &pStuNew->num);
if(pStuNew->num == -1)//输入-1返回主菜单
{
while ((c = getchar()) != EOF && c != '\n');//不停地使用getchar()获取缓冲中字符,直到获取的c是“\n”或文件结尾符EOF为止
free(pStuNew);
return hasAdd;
}
else if(checkStuIDExist(pStuNew->num))
{
while ((c = getchar()) != EOF && c != '\n');//不停地使用getchar()获取缓冲中字符,直到获取的c是“\n”或文件结尾符EOF为止
printf("该学号已存在,请重新输入!\n");
free(pStuNew);
continue;
}
hasAdd = true;
scanf("%s %s %f %f %f", pStuNew->name, pStuNew->sex, &pStuNew->score[0],
&pStuNew->score[1], &pStuNew->score[2]);
pStuNew->averge = (pStuNew->score[0] + pStuNew->score[1] + pStuNew->score[2]) / 3;
pStuNew->pNext = NULL;
pStu->pNext = pStuNew;
pStu = pStuNew;
}
return hasAdd;
}
/************************************************************************/
/根据指令序号执行对应功能 /
/**********************************************************************/
bool orderToExecute(int order)
{
bool succ;
succ = false;
if(order != Func_Save && order != Func_AutoSave && order!= Func_Export)
{
system("CLS");
showSystemTitle();
}
switch (order)
{
case Func_Add://添加
{
succ = addStudentInfo();
break;
}
case Func_Delete://删除
{
succ = deleteStudentInfo();
break;
}
case Func_Modify://修改
{
succ = modifyStudentInfo();
break;
}
case Func_Search://搜索
{
searchStudentInfo();
break;
}
case Func_Sort://排序
{
succ = sortStudentInfo();
break;
}
case Func_Save://保存
{
succ = saveStudentInfo();
if(succ)
{
gotoxy(42, Func_Save + 3);
setFontColor(LIGHTGREEN);
printf("保存成功!");
setFontColor(WHITE);
gotodelete(0, Func_ExitSystem + 4, 2);
gotoxy(0, Func_ExitSystem + 4);
}
return false;
}
case Func_AutoSave://设置自动保存
{
G_autoStore = ! G_autoStore;
printAutoStoreInfo();
orderToExecute(Func_Save);//保存配置
break;
}
case Func_Vote://投票系统
{
voteSystem();
break;
}
case Func_Export://导出所有学生信息(明文)
{
succ = exportStudentInfo();
gotoxy(17, Func_Export + 3);
setFontColor(LIGHTGREEN);
if(succ)
{
printf("导出成功!");
}
else
{
printf("导出失败!");
}
setFontColor(WHITE);
gotodelete(0, Func_ExitSystem + 4, 2);
gotoxy(0, Func_ExitSystem + 4);
return false;
}
default:
{
break;
}
}
return succ;
}
int main(int argc, char* argv[])
{
int order;
bool succ;
system("title 学生管理系统 by 机智蛋");
order = 0;
succ = false;
G_pStuHead = (Student*)malloc(sizeof(Student));
G_pStuHead->pNext = NULL;
loadStudentInfo();
while(1)
{
if(order != Func_Save && order != Func_AutoSave && order != Func_Export)//当输入这几个指令时不需要初始化屏幕
{
initScreen();
}
if(succ && order != Func_Save && G_autoStore)//执行自动保存
{
orderToExecute(Func_Save);
}
succ = false;
do
{
scanf("%d", &order);
if(order >= Func_Add && order <= Func_ExitSystem)
{
break;
}
else
{
printf("指令错误,请重新输入\n");
}
} while (1);
if(order == Func_ExitSystem)//退出
{
printf("欢迎下次继续使用,拜拜~~\n");
return 0;
}
succ = orderToExecute(order);//执行功能
}
return 0;
}
用C语言实现一个学生成绩管理系统,具体需求如下:
(1)选项菜单集成各功能函数模块
(2)录入学生成绩(姓名、学号、语文、数学成绩,总分自动计算)
(3)按总分排名次
(4)按姓名查找某学生成绩
(5)统计各课程的平均分、及格率、最高分、最低分
(6)打印成绩表
(7)退出
二.设计分析:
因为使用C语言,直接在终端(cmd命令行)进行编译运行。要有文字提示(即菜单选项)。
请选择你要本系统实现的功能:
1:学生信息浏览功能
2:统计各课程的平均分、及格率、最高分、最低分
3:单用户信息查询功能
4:排序功能(按学生总分绩进行排序)
5:安全退出
通过输入1~5,来执行相应的功能,每个功能项都对应于一个函数,根据用户的输入,去调用不同的函数,这样,模块比较清晰。
将上面5个函数封装在一个函数中,即mixed(m,n),通过参数n的不同,从而调用不同的功能。
提供了一个input函数,用于输入学生信息。
在程序主函数(即main)中, 通过调用printf来显示选项菜单;调用input进行数据的录入;调用mixed去真正执行对应的功能。
对于功能操作,有两点要注意:
(1)要对用户的输入进行check,如果是1~5之间的数据,则是正确的,就去调用mixed,否则,程序直接退出。
(2)在功能操作过程中,是一个无限循环,要退出这个循环,必须通过菜单选项“5:安全退出”功能才能退出这个循环,而且,退出循环的同时,也意味着程序结束了。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 175
typedef struct mark
{
double yuwen;
double shuxue;
}mark;
typedef struct
{
long number;
char name[20];
double sum;
double aver;
mark achie;
}student;
student stu[N];
double ymin,ymax,smax,smin,yper,sper,yaver=0,saver=0;
int input()
{
int i,n;
printf("请输入你要输入的学生数:\n");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
printf("请输入第%d个学生的信息(包括学号、姓名、语文、数学的成绩)\n",i);
scanf(
"%ld%s%lf%lf",
&stu[i].number,
stu[i].name,
&stu[i].achie.yuwen,
&stu[i].achie.shuxue
);
}
return(n);
} /* end input() */
void skim(int n)
{
int i;
printf("列出的学生信息依次为学号、姓名、语文、数学的成绩、总分、平均分\n");
for(i=1;i<=n;i++)
{
stu[i].sum=stu[i].achie.yuwen+stu[i].achie.shuxue;
stu[i].aver=stu[i].sum/2.0;
printf("第%d个学生的信息为:\n",i);
printf(
"%d\t%s\t%lf\t%lf\t",
stu[i].number,
stu[i].name,
stu[i].achie.yuwen,
stu[i].achie.shuxue
);
printf("%lf\t%lf\n",stu[i].sum,stu[i].aver);
}
} /* end skim() */
void search(int n,char m[])
{
int i;
for(i=1;i<=n;i++)
if(strcmp(stu[i].name,m)==0)
break;
if(i>n)
printf("系统查找不到相应学生的信息,请确认输入后重新输入\n");
else
{
stu[i].sum=stu[i].achie.yuwen+stu[i].achie.shuxue;
stu[i].aver=stu[i].sum/2.0;
printf("你要查询的学生的信息是:");
printf("%d\t%s\t%lf\t%lf\t",stu[i].number,stu[i].name,stu[i].achie.yuwen,stu[i].achie.shuxue);
printf("%lf\t%lf\n",stu[i].sum,stu[i].aver);
}
} /* end search() */
void sort(int n)
{
int i,j;
student temp;
for(i=1;i<=n;i++)
{
stu[i].sum=stu[i].achie.yuwen+stu[i].achie.shuxue;
stu[i].aver=stu[i].sum/2.0;
}
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
if(stu[i].sum>stu[j].sum)
{
temp=stu[i];
stu[i]=stu[j];
stu[j]=temp;
}
printf("按学生的总分升序排序后的结果是:");
for(i=1;i<=n;i++)
{
printf("%d\t%s\t%lf\t%lf\t",stu[i].number,stu[i].name,stu[i].achie.yuwen,stu[i].achie.shuxue);
printf("%lf\t%lf\n",stu[i].sum,stu[i].aver);
}
} /* end sort() */
void stati(int n)
{
int i,a=0,b=0;
ymin=stu[1].achie.yuwen;smin=stu[1].achie.shuxue;
ymax=stu[1].achie.yuwen;smax=stu[1].achie.shuxue;
for(i=1;i<=n;i++)
{
if(stu[i].achie.yuwen<ymin)
ymin=stu[i].achie.yuwen;
if(stu[i].achie.yuwen>ymax)
ymax=stu[i].achie.yuwen;
if(stu[i].achie.shuxue<smin)
smin=stu[i].achie.shuxue;
if(stu[i].achie.shuxue>smax)
ymin=stu[i].achie.shuxue;
if(stu[i].achie.yuwen>=60) a++;
if(stu[i].achie.shuxue>=60) b++;
saver+=stu[i].achie.shuxue/2.0;
yaver+=stu[i].achie.yuwen/2.0;
}
yper=(double)a;
sper=(double)b;
printf("语文的平均分、及格率、最高分、最低分分别为:%lf\t%lf\t%lf\t%lf\n",yaver,yper,ymax,ymin);
printf("数学的平均分、及格率、最高分、最低分分别为:%lf\t%lf\t%lf\t%lf\n",saver,sper,smax,smin);
} /* end stati() */
void mixed(int m,int n)
{
char k[N];
switch(m)
{
case 1:skim(n);
break;
case 2:stati(n);
break;
case 3:printf("请输入你要查询的学生的姓名:");
scanf("%s",k);
search(n,k);
break;
case 4:sort(n);
break;
case 5:exit(0);
}
} /* end mixed() */
void main()
{
int n,m;
printf("\n\t为使系统正常工作请先按提示输入学生信息\n\n");
n=input();
printf("%d",n);
do
{
printf("请选择你要本系统实现的功能:\n");
printf("1:学生信息浏览功能\n");
printf("2:统计各课程的平均分、及格率、最高分、最低分\n");
printf("3:单用户信息查询功能\n");
printf("4:排序功能(按学生总分绩进行排序)\n");
printf("5:安全退出\n");
printf("\t\t\t\t\t\t请输入你要实现的功能选项:");
scanf("%d",&m);
printf("\n");
if(m<0||m>4)
{
printf("程序即将退出!\n");
break;
}
else
mixed(m,n);
}while(1);
return;
} /* end main() */