1、题目内容:
现有学生成绩信息,内容如下
姓名 学号 语文 数学 英语
张明明 01 67 78 82
李成友 02 78 91 88
张辉灿 03 68 82 56
王露 04 56 45 77
陈东明 05 67 38 47
… … … … …
请用 C/C++编写一系统,实现学生信息管理,软件的入口界面应包括如下几个方面:
(一)功能要求:
(1) 信息维护:要求:学生信息数据要以文件的形式保存,能实现学生信息数据的维护。此模块包括子模块有:增加学生信息、删除学生信息、修改学生信息
(2) 信息查询:要求:查询时可实现按姓名查询、按学号查询
(3) 成绩统计:要求:A 输入任意的一个课程名(如数学)和一个分数段(如 60–70),统计出在此分数段的学生情况。
(4) 排序:能对用户指定的任意课程名,按成绩升序或降序排列学生数据并显示排序结果(使用表格的形式显示排序后的输出结果)(使用多种方法排序者,加分)
(二)其它要求:
(1) 只能使用 C/C++语言,源程序要有适当的注释,使程序容易阅读
(2) 至少采用文本菜单界面(如果能采用图形菜单界面更好)
(3) 学生可自动增加新功能模块(视情况可另外加分)
(4)写出课程设计报告,具体要求见相关说明
2、主要功能:
1.增加学生信息
2.删除学生信息
3.修改学生信息
4.信息查询
5.成绩统计
6.排序
7.展示所有学生信息
3、源代码:
3.1 main.cpp:
#include <iostream>
#include "Student.h"
#include <stdlib.h>
using namespace std;
int main()
{
Student student;
int choice;
while(true){
cout<<"*********************"<<endl;
cout<<" 功能表 "<<endl;
cout<<"1.增加学生信息\n"<<"2.删除学生信息\n"<<"3.修改学生信息\n"<<"4.信息查询\n"<<"5.成绩统计\n"<<"6.排序\n"<<"7.展示所有学生信息\n"<<"8.退出系统\n";
cout<<"*********************"<<endl;
cin>>choice;
switch(choice){
case 1:
student.addStudent();
break;
case 2:
student.deleteStudent();
break;
case 3:
student.alterMessage();
break;
case 4:
student.searchMessage();
break;
case 5:
student.countPerson();
break;
case 6:
student.sortMessage();
break;
case 7:
student.display();
break;
case 8:
exit(0);
default:
cout<<"没有此功能!"<<endl;
}
}
}
3.2 Student.h:
#ifndef STUDENT_H_INCLUDED
#define STUDENT_H_INCLUDED
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <fstream>
using namespace std;
class Student{
char name[20]; //学生的名字
char num[20]; //学生的学号
int chinese; //语文成绩
int math; //数学成绩
int english; //英语成绩
int totalScore; //自己增设总分(由三科成绩决定)
public:
class invalidScore{};
int getTotalScore(){totalScore=chinese+math+english;return totalScore;};
//内联函数,求总分
void show(); //显示当前学生信息,每调用一次显示当前调用的学生信息,用于单独对学生信息的改变
void showExcel(); //以表格的形式显示学生信息
void display(); //显示所有学生信息
void addStudent(); //增加学生信息
void deleteStudent(); //删除学生信息
void alterMessage(); //修改学生信息
void searchMessage(); //查询学生信息
void searchName(); //按名字查找
void searchNum(); //按学号查找
void countPerson(); //计算符合某科目某分数区间的学生信息
void countChinese(); //计算符合语文的学生信息
void countMath(); //计算符合数学的学生信息
void countEnglish(); //计算符合英语的学生信息
void sortMessage(); //按科目排序学生分数
};
#endif // STUDENT_H_INCLUDED
3.3 Student.cpp
#include <iostream>
#include <string>
#include <fstream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <iomanip>
#include "Student.h"
using namespace std;
void Student::show(){
cout<<"该学生姓名:"<<name<<"\n该学生学号:"<<num<<"\n语文成绩:"<<chinese<<"\n数学成绩:"<<math<<"\n英语成绩:"<<english<<"\n总分:"<<totalScore<<endl;
}
void Student::showExcel(){
cout<<name<<"\t "<<num<<" \t"<<chinese<<"\t "<<math<<" \t"<<english<<"\t "<<totalScore<<" \t "<<endl;
}
void Student::display(){
fstream file("Student.txt",ios::binary|ios::in);
cout<<"学生姓名 学号 语文成绩 数学成绩 英语成绩 总分"<<endl;
//当没有读到文件末尾时,每次初始化一个对象,每次以该类的长度将文件读到该对象
while(!file.eof())
{
Student stu;
file.read((char *)&stu,sizeof(Student)); //从文件读出所有学生信息
if(file.fail()) break; //这一句很重要,因为即使读到文件末尾,对象file还会多读取一次,使得结果不怎么好看
cout<<stu.name<<"\t "<<stu.num<<" \t"<<stu.chinese<<"\t "<<stu.math<<" \t"<<stu.english<<"\t "<<stu.totalScore<<" \t "<<endl;
}
file.close();
}
void Student::addStudent(){
//初始化一个对象,以追加的方式将文件打开
Student stu;
fstream file;
file.open("Student.txt",ios::binary|ios::out|ios::app);
cout<<"请输入该学生的名字:";
cin>>stu.name;
cout<<"请输入该学生的学号:";
cin>>stu.num;
cout<<"请输入该学生的语文成绩:";
cin>>stu.chinese;
if(stu.chinese>100||stu.chinese<0) throw invalidScore();
cout<<"请输入该学生的数学成绩:";
cin>>stu.math;
if(stu.math>100||stu.math<0) throw invalidScore();
cout<<"请输入该学生的英语成绩:";
cin>>stu.english;
if(stu.english>100||stu.english<0) throw invalidScore();
stu.getTotalScore(); //求总分
cout<<endl;
if(file.fail()){
cout<<"打开文件Student.txt出错!";
exit(0);
}
file.write((char *)&stu,sizeof(Student));
file.close();
}
//主要思想是不将删除的学生读入文件,实现删除的功能
void Student::deleteStudent(){
Student student[50]; //对象数组
int position=0,here; //position是读文件读到的位置,here是删除学生的位置
char str[20]; //暂时用来存放所查找学生的名字
int tab=0; //标记是否存在该学生
fstream file("Student.txt",ios::binary|ios::in);
cout<<"请输入要删除的学生的姓名:";
cin>>str;
//将文件读到对象数组
while(!file.eof()){
file.read((char *)&student[position],sizeof(Student));
if(strcmp(student[position].name,str)==0){ //比较输入的名字与从文件读到对象数组的名字是否相同
tab=-1;
cout<<"所删除的学生信息为:"<<endl;
here=position;
student[here].show();
}
position++;
}
if(tab!=-1){
cout<<"删除的学生不存在!"<<endl;
exit(0);
}
file.close();
fstream file0("Student.txt",ios::binary|ios::out);
for(int i=0;i<position-1;i++){
if(i==here){
//略过所删除学生的位置,不将其读入文件,从而实现删除学生的功能
}
else
file0.write((char *)&student[i],sizeof(Student));
}
cout<<"删除成功!"<<endl;
file.close();
return;
}
//创建对象数组,将文件读入其中,并定位删除学生在对象数组的下标,对其进行修改各项信息的操作
void Student::alterMessage(){
int chioce,chinese,math,english,position=0,here; //chioce为选择修改的项目,chinese为语文成绩,依此类推
Student student[50];
int tab=0;
char str[20]; //暂时储存所要修改的内容
fstream file("Student.txt",ios::binary|ios::in);
cout<<"请输入要修改的学生的姓名:";
cin>>str;
//读文件到对象数组,并定位
while(!file.eof()){
file.read((char *)&student[position],sizeof(Student));
if(strcmp(student[position].name,str)==0){
tab=-1;
cout<<"所修改的学生信息为:"<<endl;
here=position; //定位
student[here].show();
}
position++;
}
if(tab!=-1){
cout<<"修改的学生不存在!"<<endl;
exit(0);
}
file.close();
//修改菜单,有时并不需要修改此学生的全部信息
printf("------------------\n");
cout<<"1.修改名字"<<endl;
cout<<"2.修改学号"<<endl;
cout<<"3.修改语文成绩"<<endl;
cout<<"4.修改数学成绩"<<endl;
cout<<"5.修改英语成绩"<<endl;
cout<<"6.退出菜单"<<endl;
printf("------------------\n");
while(1){
printf("请选择功能:");
cin>>chioce;
switch(chioce){
case 1:
cout<<"请输入新的姓名:";
cin>>str;
strcpy(student[here].name,str);
break;
case 2:
cout<<"请输入新的学号:";
cin>>str;
strcpy(student[here].num,str);
break;
case 3:
cout<<"请输入新的语文成绩:";
cin>>chinese;
student[here].chinese=chinese;
student[here].getTotalScore(); //因分数修改过了,需重新计算总分
break;
case 4:
cout<<"请输入新的数学成绩:";
cin>>math;
student[here].math=math;
student[here].getTotalScore();
break;
case 5:
cout<<"请输入新的英语成绩:";
cin>>english;
student[here].english=english;
student[here].getTotalScore();
break;
case 6:{
//只有在退出这个菜单时,才一次性将所修改的学生的信息写入文件,避免了进行多次操作时反复写入文件
fstream file("Student.txt",ios::binary|ios::out);
cout<<"修改成功!"<<endl;
cout<<endl;
for(int i=0;i<position-1;i++){
file.write((char *)&student[i],sizeof(Student)); //把新的学生信息写入文件
}
file.close();
return;
}
default:
cout<<"没有此选项!请重新输入!"<<endl;
}
}
}
void Student::searchMessage(){
int choice;
cout<<"请选择以下一种方式查询学生信息:\n";
cout<<"1.姓名 2.学号"<<endl;
cin>>choice;
switch(choice){
case 1:
searchName();
break;
case 2:
searchNum();
break;
default:
cout<<"没有此选项!";
}
}
void Student::searchName(){
char str[20]; //所要查询的学生名字
int tab=0;
cout<<"请输入该学生的姓名:";
cin>>str;
fstream file("Student.txt",ios::binary|ios::in);
while(!file.eof()){
Student stu;
file.read((char *)&stu,sizeof(Student));
if(strcmp(stu.name,str)==0){
tab=-1;
stu.show(); //显示匹配的学生的信息
break;
}
}
if(tab!=-1) cout<<"不存在此学生的信息!"<<endl;
file.close();
}
void Student::searchNum(){
char str[20]; //所要查询的学生学号
int tab=0;
cout<<"请输入该学生的学号:";
cin>>str;
fstream file("Student.txt",ios::binary|ios::in);
while(!file.eof()){
Student stu;
file.read((char *)&stu,sizeof(Student));
if(strcmp(stu.num,str)==0){
tab=-1;
stu.show();
break;
}
}
if(tab!=-1) cout<<"不存在此学生的信息!"<<endl;
file.close();
}
void Student::countPerson(){
int choice;
cout<<"请选择统计的科目:"<<endl;
cout<<"1.语文 2.数学 3.英语"<<endl;
cin>>choice;
switch(choice){
case 1:
countChinese();
break;
case 2:
countMath();
break;
case 3:
countEnglish();
break;
default:
cout<<"没有此科目!";
}
}
//也是类似的创建对象数组,将文件读入,并确定该学生的成绩是否在某分数区间
void Student::countChinese(){
int low,high,count=0,position=0; //count为符合条件的学生人数
Student student[50];
fstream file("Student.txt",ios::binary|ios::in);
cout<<"请输入统计的分数区间:"<<endl;
cout<<"最低分数:";
cin>>low;
cout<<"最高分数:";
cin>>high;
while(!file.eof()){
file.read((char *)&student[position],sizeof(Student));
if(student[position].chinese>=low&&student[position].chinese<=high){
count++;
if(count==1){
cout<<"学生的信息如下:"<<endl;
cout<<"学生姓名 学号 语文成绩 数学成绩 英语成绩 总分"<<endl;
}
student[position].showExcel();
}
position++;
}
if(count!=0){
cout<<"在此区间内的学生人数为:"<<count<<endl;
}
else{
cout<<"没有学生符合条件!"<<endl;
}
file.close();
}
void Student::countMath(){
int low,high,count=0,position=0;
Student student[50];
fstream file("Student.txt",ios::binary|ios::in);
cout<<"请输入统计的分数区间:"<<endl;
cout<<"最低分数:";
cin>>low;
cout<<"最高分数:";
cin>>high;
while(!file.eof()){
file.read((char *)&student[position],sizeof(Student));
if(student[position].math>=low&&student[position].math<=high){
count++;
if(count==1){
cout<<"学生的信息如下:"<<endl;
cout<<"学生姓名 学号 语文成绩 数学成绩 英语成绩 总分"<<endl;
}
student[position].showExcel();
}
position++;
}
if(count!=0){
cout<<"在此区间内的学生人数为:"<<count<<endl;
}
else{
cout<<"没有学生符合条件!"<<endl;
}
file.close();
}
void Student::countEnglish(){
int low,high,count=0,position=0;
Student student[50];
fstream file("Student.txt",ios::binary|ios::in);
cout<<"请输入统计的分数区间:"<<endl;
cout<<"最低分数:";
cin>>low;
cout<<"最高分数:";
cin>>high;
while(!file.eof()){
file.read((char *)&student[position],sizeof(Student));
if(student[position].english>=low&&student[position].english<=high){
count++;
if(count==1){
cout<<"学生的信息如下:"<<endl;
cout<<"学生姓名 学号 语文成绩 数学成绩 英语成绩 总分"<<endl;
}
student[position].showExcel();
}
position++;
}
if(count!=0){
cout<<"在此区间内的学生人数为:"<<count<<endl;
}
else{
cout<<"没有学生符合条件!"<<endl;
}
file.close();
}
void Student::sortMessage(){
int choice,updown,position=0; //updown为升序或降序的选择
cout<<"请选择排序的方式:"<<endl;
cout<<"1.语文 2.数学 3.英语 4.总分"<<endl;
cin>>choice;
Student student[50];
Student *point=student; //指向已经定义的对象数组
fstream file("Student.txt",ios::binary|ios::in);
while(!file.eof()){
file.read((char *)&student[position],sizeof(Student));
position++;
}
file.close();
switch(choice){
case 1:
cout<<"请选择排序的方式"<<endl;
cout<<"1.升序 2.降序"<<endl;
cin>>updown;
//冒泡排序,升序
if(updown==1){
for(int i=0;i<position-1;i++){
for(int j=0;j<position-1-i;j++){
if(student[j].chinese>student[j+1].chinese){
Student temp=student[j];
student[j]=student[j+1];
student[j+1]=temp;
}
}
}
for(int i=0;i<position-1;i++){
if(i==0) cout<<"学生姓名 学号 语文成绩 数学成绩 英语成绩 总分"<<endl;
student[i].showExcel();
}
}
//降序排数
if(updown==2){
//通过摸索出来的i<position-2,我也不是很清楚为什么-2,而不是-1
for(int i=0;i<position-2;i++){
for(int j=0;j<position-2-i;j++){
if(student[j].chinese<student[j+1].chinese){
Student temp=student[j];
student[j]=student[j+1];
student[j+1]=temp;
}
}
}
for(int i=0;i<position-1;i++){
if(i==0) cout<<"学生姓名 学号 语文成绩 数学成绩 英语成绩 总分"<<endl;
student[i].showExcel();
}
}
break;
case 2:
cout<<"请选择排序的方式"<<endl;
cout<<"1.升序 2.降序"<<endl;
cin>>updown;
if(updown==1){
for(int i=0;i<position-1;i++){
for(int j=0;j<position-1-i;j++){
if(student[j].math>student[j+1].math){
Student temp=student[j];
student[j]=student[j+1];
student[j+1]=temp;
}
}
}
for(int i=0;i<position-1;i++){
if(i==0) cout<<"学生姓名 学号 语文成绩 数学成绩 英语成绩 总分"<<endl;
student[i].showExcel();
}
}
if(updown==2){
for(int i=0;i<position-2;i++){
for(int j=0;j<position-2-i;j++){
if(student[j].math<student[j+1].math){
Student temp=student[j];
student[j]=student[j+1];
student[j+1]=temp;
}
}
}
for(int i=0;i<position-1;i++){
if(i==0) cout<<"学生姓名 学号 语文成绩 数学成绩 英语成绩 总分"<<endl;
student[i].showExcel();
}
}
break;
case 3:
cout<<"请选择排序的方式"<<endl;
cout<<"1.升序 2.降序"<<endl;
cin>>updown;
if(updown==1){
for(int i=0;i<position-1;i++){
for(int j=0;j<position-1-i;j++){
if(student[j].english>student[j+1].english){
Student temp=student[j];
student[j]=student[j+1];
student[j+1]=temp;
}
}
}
for(int i=0;i<position-1;i++){
if(i==0) cout<<"学生姓名 学号 语文成绩 数学成绩 英语成绩 总分"<<endl;
student[i].showExcel();
}
}
if(updown==2){
for(int i=0;i<position-2;i++){
for(int j=0;j<position-2-i;j++){
if(student[j].english<student[j+1].english){
Student temp=student[j];
student[j]=student[j+1];
student[j+1]=temp;
}
}
}
for(int i=0;i<position-1;i++){
if(i==0) cout<<"学生姓名 学号 语文成绩 数学成绩 英语成绩 总分"<<endl;
student[i].showExcel();
}
}
break;
case 4:
cout<<"请选择排序的方式"<<endl;
cout<<"1.升序 2.降序"<<endl;
cin>>updown;
//尝试使用指针
if(updown==1){
for(int i=0;i<position-1;i++){
for(int j=0;j<position-1-i;j++){
if(point[j].totalScore>point[j+1].totalScore){
Student temp=point[j];
point[j]=point[j+1];
point[j+1]=temp;
}
}
}
for(int i=0;i<position-1;i++){
if(i==0) cout<<"学生姓名 学号 语文成绩 数学成绩 英语成绩 总分"<<endl;
point[i].showExcel();
}
}
if(updown==2){
for(int i=0;i<position-2;i++){
for(int j=0;j<position-2-i;j++){
if(point[j].totalScore<point[j+1].totalScore){
Student temp=point[j];
point[j]=point[j+1];
point[j+1]=temp;
}
}
}
for(int i=0;i<position-1;i++){
if(i==0) cout<<"学生姓名 学号 语文成绩 数学成绩 英语成绩 总分"<<endl;
point[i].showExcel();
}
}
break;
default:
cout<<"没有此科目!";
delete []point;
}
}
4、写在后面
这是博主大二上学期写的,现在C++语法基本忘光了,写得也就那样,大伙将就着看吧…然后需要说明一下,这个小系统的小特色是读写信息到txt文件是以整个对象的形式进行的,所以txt文件打开会出现乱码(也许、大概、可能是这个原因…如下图),但是对功能没有什么影响,然后排序采用的是简单的冒泡排序,感兴趣的小伙伴可以尝试着去解决乱码的问题,试着用其他较为复杂的方法排序,还有就是文件基本是用Dev-C++编写的。如果还要啥不足的,请多多指教。