#include<iostream>
#include<iomanip>
#include<string>
#include<fstream>
#include<windows.h>
#include<math.h>
#include<sys\stat.h>
using namespace std;
string strFilePathName3;
const int FilePathLen = 1024;
const int ClassNameLen = 32;
//-------------------------------------
//----------学生信息结构---------------
//-------------------------------------
struct StudentMessage
{
int nNo; //学号
char chName[10]; //姓名
char chCourse[20]; //专业
char chGender[8]; //性别
float fComprehensive; //综合成绩
int nBirthdate; //出生日期
int nAge; //年龄
//本科生
float fEnglishResults; //本科生英语成绩
//研究生
int nThesisCount; //研究生发表论文数量
StudentMessage *pNext; //指向下一个学生的指针
};
//-------------------------------------
//------------函数预定义---------------
//-------------------------------------
bool FileExist (string strFilePathName); //判断文件数否存在
bool IsDirectory(string strDirNaem); //判断目录是否存在
string GetMessageFileName(); //根据输入文件目录及班级名称生成数据文件全名称
bool FreeMem(StudentMessage *pRsHead); //释放链表
bool MessageToFile(string strFilePathName,StudentMessage* pStHead,int nSign=1); //保存数据到文件
StudentMessage* MessageFromFile(string strFilePathName); //从文件中读取学生信息
bool StudentMessageInput(); //学生信息输入
bool MessageDelete(StudentMessage* pStHead,string strFilePathName); //信息删除
void Display(StudentMessage *pStHead,int nNum,int nSign); //显示学生信息
bool MessageBrowser(); //浏览学生信息
void InquiryByNo(); //按学号检索
int InquiryByName(); //按姓名检索
void MessageUpdate(StudentMessage *pStHead,StudentMessage *pStCur,string strFilePathName,int nSign); //信息修改
void ResultsAverage(); //本科生综合平均成绩、英语平均成绩
void nThesisCountSort(StudentMessage* pStHead,int nAscending); //研究生按论文数量排序
int MenuMain(); //系统菜单
bool MessageInquiry(); //成绩查询
//-------------------------------------
//-------------函数实现----------------
//-------------------------------------
//判断文件是否存在-------------------------
bool FileExist(string strFilePathName)
{
int StudentMessage;
struct _stat buf;
StudentMessage= _stat(strFilePathName.c_str(),&buf);
return(StudentMessage==0);
}
//判断目录是否存在-------------------------
bool IsDirectory(string strDirName)
{
struct _stat buf;
if(_stat(strDirName.c_str(),&buf)!=0) //判断是否存在
{
return false;
}
return ((buf.st_mode&S_IFDIR)!=0);
}
//根据输入文件目录及班级名称生成数据文件全名称-------------------------
string GetMessageFileName()
{
char chFilePath[FilePathLen]; //文件存放目录
char chClass[ClassNameLen]; //班级名称
string strFilePathName;
string strFilePathName2;
//输入成绩存放目录及班级
//cin.ignore();
cout<<"请输入文件目录:";
cin.getline(chFilePath,FilePathLen);
strFilePathName=string(chFilePath);
while(!IsDirectory(strFilePathName))
{
cout<<"目录:"<<strFilePathName<<"不存在,请重新输入!"<<endl;
cin.getline(chFilePath,FilePathLen);
strFilePathName=string(chFilePath);
}
int nLen=strFilePathName.length();
int nPos=strFilePathName.find_last_of('\\',nLen);
if(nPos!=nLen)
{
strFilePathName=strFilePathName+string("\\");
}
strFilePathName2=strFilePathName;
//输入班级成绩
cout<<"请输入班级名称:";
cin.getline(chClass,ClassNameLen);
//
strFilePathName=strFilePathName+string(chClass)+string(".dat");
while(!FileExist(strFilePathName))
{
cout<<"文件:"<<strFilePathName<<"不存在,请重新输入!"<<endl;
cin.getline(chClass,ClassNameLen);
strFilePathName=strFilePathName2+string(chClass)+string(".dat");
}
return strFilePathName;
}
//释放链表内存-------------------------
bool FreeMem(StudentMessage* pStHead)
{
StudentMessage *pStCur;
if(pStHead==NULL)
return false;
do
{
pStCur=pStHead;
pStHead=pStHead->pNext;
delete pStCur;
}while(pStHead!=NULL);
return true;
}
//保存数据到文件-------------------------
bool MessageToFile(string strFilePathName,StudentMessage* pStHead,int nSign)
{
StudentMessage* pStCur;
ofstream fileOut;
//
if(pStHead==NULL)
return false;
//已追加方式打开文件
if(nSign==1)
fileOut.open(strFilePathName.c_str(),ios::out|ios::app|ios::binary);
//如果文件存在,把文件长度设为0/文件更新
if(nSign==0)
fileOut.open(strFilePathName.c_str(),ios::out|ios::trunc|ios::binary);
if(fileOut.fail())
{
cout<<"Can not open file:"<<strFilePathName<<endl;
return false;
}
//保存成绩
pStCur=pStHead;
while(pStCur!=NULL)
{
fileOut.write((char*)pStCur,sizeof(*pStCur));
pStCur=pStCur->pNext;
};
//关闭文件
fileOut.close();
return true;
}
//从给定文件读取学生成绩------------------------------
StudentMessage* MessageFromFile(string strFilePathName)
{
SYSTEMTIME systime; //windows.h中的函数
GetLocalTime(&systime); //获取当前时间
StudentMessage *pStNew,*pStHead=NULL;
ifstream fileIn;
//打开文件
fileIn.open(strFilePathName.c_str(),ios::in|ios::binary); //binary:二进制方式
if(fileIn.fail())
{
cout<<"Can not open file:"<<strFilePathName<<endl;
return pStHead;
}
//成绩记录
while(!fileIn.eof())
{
pStNew=new StudentMessage;
fileIn.read((char*)pStNew,sizeof(*pStNew));
int ng=fileIn.gcount();
if(ng==0)
{
delete pStNew;
break;
}
//根据不同的出生日期输入格式,计算年龄
if(pStNew->nBirthdate/10000>=1)
{
pStNew->nAge=systime.wYear-pStNew->nBirthdate/10000;
}
else
{
pStNew->nAge=systime.wYear-pStNew->nBirthdate;
}
pStNew->pNext=NULL;
if(pStHead==NULL)
pStHead=pStNew;
else
{
pStNew->pNext=pStHead;
pStHead=pStNew;
}
}
fileIn.close();
return pStHead;
}
//成绩录入-------------------------
void StudentMessageInput(int nSign)
{
char chChoice;
bool bFileExist;
//string strFilePathName;
//录入班级和文件存放目录
//strFilePathName=GetMessageFileName();
bFileExist=FileExist(strFilePathName3);
if(bFileExist)
{
cout<<"文件"<<strFilePathName3<<"已存在,是否追加(Y/N)";
cin>>chChoice;
if(toupper(chChoice)=='N')
return ;
}
StudentMessage *pStHead=NULL;
StudentMessage *pStNew,*pStPrev;
//录入所有学生成绩
cout<<"请依次输入每位学生信息,学号为 -1 结束输入"<<endl;
do
{
pStNew=new StudentMessage;
pStNew->pNext=NULL;
pStNew->fComprehensive=0;
pStNew->nBirthdate=0;
pStNew->nAge=0;
pStNew->fEnglishResults=0;
pStNew->nThesisCount=0;
cout<<"学号:";
cin>>pStNew->nNo;
if(pStNew->nNo==-1)
{
delete pStNew;
break;
}
cout<<"姓名:"; cin>>pStNew->chName;
cout<<"专业:"; cin>>pStNew->chCourse;
cout<<"性别:"; cin>>pStNew->chGender;
cout<<"出生日期:"; cin>>pStNew->nBirthdate;
cout<<"综合成绩:"; cin>>pStNew->fComprehensive;
if(nSign==0)
{
cout<<"英语成绩:"; cin>>pStNew->fEnglishResults;
}
else
{
cout<<"论文数量:"; cin>>pStNew->nThesisCount;
}
if(pStHead==NULL)
pStHead=pStNew;
else
{
pStPrev=pStHead;
while(pStPrev->pNext!=NULL)
pStPrev=pStPrev->pNext;
pStPrev->pNext=pStNew;
}
}while(true);
//bool bMes;
// bMes=MessageToFile(strFilePathName3,pStHead);
//释放内存
FreeMem(pStHead);
//return bMes;
}
//显示学生信息-----------------------------------
void Display(StudentMessage *pStHead,int nNum,int nSign)
{
StudentMessage* pStCur;
//
if(pStHead==NULL)
{
cout<<"没有数据!"<<endl;
return;
}
pStCur=pStHead;
//显示单个学生成绩
if(nNum==1)
{
cout<<"学号:"<<pStCur->nNo<<endl;
cout<<"姓名:"<<pStCur->chName<<endl;
cout<<"性别:"<<pStCur->chGender<<endl;
cout<<"专业:"<<pStCur->chCourse<<endl;
cout<<"出生日期:"<<pStCur->nBirthdate<<endl;
cout<<"年龄:"<<pStCur->nAge<<endl;
cout<<"综合成绩:"<<pStCur->fComprehensive<<endl;
if(nSign==0)
cout<<"英语成绩:"<<pStCur->fEnglishResults<<endl;
else
cout<<"论文数量:"<<pStCur->nThesisCount<<endl;
return;
}
else
{
//显示所有学生成绩
cout<<setw(5)<<"学号"<<setw(10)<<"姓名"<<setw(8)<<"性别";
cout<<setw(10)<<"专业"<<setw(10)<<"出生日期"<<setw(5)<<"年龄";
cout<<setw(10)<<"综合成绩"<<setw(10);
if(nSign==0)
cout<<"英语成绩"<<endl;
else
cout<<"论文数量"<<endl;
do
{
if(nSign==0)
{
if(pStCur->fEnglishResults)
{
cout<<setw(5)<<pStCur->nNo;
cout<<setw(10)<<pStCur->chName;
cout<<setw(8)<<pStCur->chGender;
cout<<setw(10)<<pStCur->chCourse;
cout<<setw(10)<<pStCur->nBirthdate;
cout<<setw(5)<<pStCur->nAge;
cout<<setw(10)<<pStCur->fComprehensive;
cout<<setw(10)<<pStCur->fEnglishResults;
}
}
else
{
if(pStCur->nThesisCount)
{
cout<<setw(5)<<pStCur->nNo;
cout<<setw(10)<<pStCur->chName;
cout<<setw(8)<<pStCur->chGender;
cout<<setw(10)<<pStCur->chCourse;
cout<<setw(10)<<pStCur->nBirthdate;
cout<<setw(5)<<pStCur->nAge;
cout<<setw(10)<<pStCur->fComprehensive;
cout<<setw(10)<<pStCur->nThesisCount;
}
}
cout<<endl;
pStCur=pStCur->pNext;
}while(pStCur!=NULL);
}
return;
}
//信息浏览--------------------------------------
bool MessageBrowser(int nSign)
{
//string strFilePathName;
ifstream fileIn;
//
//strFilePathName=GetMessageFileName();
StudentMessage *pStHead;
//成绩记录
pStHead =MessageFromFile(strFilePathName3);
Display(pStHead,0,nSign);
FreeMem(pStHead);
return true;
}
//信息删除--------------------------------
bool MessageDelete()
{
//string strFilePathName;
StudentMessage* pStHead=NULL;
//strFilePathName=GetMessageFileName();
pStHead =MessageFromFile(strFilePathName3);
if(pStHead==NULL)
return false;
StudentMessage* pStCur;
int nNo,nNum;
cout<<"请输入要删除的信息学生号:";
cin>>nNo;
nNum=0;
pStCur=pStHead;
if(pStCur->nNo==nNo)
{
pStCur=pStCur->pNext;
pStHead=NULL;
nNum++;
}
else
{
while(pStCur!=NULL)
{
if(pStCur->pNext->nNo==nNo&&pStCur->pNext!=NULL)
{
pStCur->pNext=pStCur->pNext->pNext;
nNum++;
break;
}
else
{
pStCur->pNext=NULL;
nNum++;
}
pStCur =pStCur->pNext;
}
}
if(nNum==0)
cout<<"学号:"<<nNo<<",无该学生成绩"<<endl;
else
cout<<"删除成功!"<<endl;
MessageToFile(strFilePathName3,pStCur,0);
FreeMem(pStCur);
return true;
}
//信息更新--------------------------------
void MessageUpdate(StudentMessage *pStHead,StudentMessage *pStCur,string strFilePathName)
{
pStCur->pNext=NULL;
pStCur->fComprehensive=0;
pStCur->nBirthdate=0;
pStCur->nAge=0;
cout<<"姓名:"; cin>>pStCur->chName;
cout<<"专业:"; cin>>pStCur->chCourse;
cout<<"性别:"; cin>>pStCur->chGender;
cout<<"出生日期:"; cin>>pStCur->nBirthdate;
cout<<"综合成绩:"; cin>>pStCur->fComprehensive;
cout<<"英语成绩:"; cin>>pStCur->fEnglishResults;
MessageToFile(strFilePathName,pStHead,0);
cout<<"修改成功!"<<endl;
}
//按学号检索-------------------------------
void InquiryByNo()
{
//string strFilePathName;
StudentMessage* pStHead=NULL;
//strFilePathName=GetMessageFileName();
pStHead =MessageFromFile(strFilePathName3);
if(pStHead==NULL)
return;
StudentMessage *pStCur;
int nNo,nNum;
cout<<"请输入要更改的信息学生号:";
cin>>nNo;
nNum=0;
pStCur=pStHead;
while(pStCur!=NULL)
{
if(pStCur->nNo==nNo)
{
nNum++;
MessageUpdate(pStHead,pStCur,strFilePathName3);
break;
}
pStCur =pStCur->pNext;
}
if(nNum==0)
cout<<"学号:"<<nNo<<",无该学生成绩"<<endl;
}
//按姓名检索学生-------------------------
int InquiryByName()
{
cin.ignore();
//string strFilePathName;
StudentMessage* pStHead=NULL;
//strFilePathName=GetMessageFileName();
pStHead =MessageFromFile(strFilePathName3);
int nNum;
char chName[20];
StudentMessage *pStCur;
cout<<"请输入查询学生姓名:";
cin.getline(chName,20);
nNum=0;
pStCur =pStHead;
while(pStCur!=NULL)
{
if((strcmp(pStCur->chName,chName)==0))
{
nNum++;
Display(pStCur,1,0);
}
pStCur=pStCur->pNext;
}
if(nNum==0)
cout<<"姓名:"<<chName<<",无该学生成绩"<<endl;
return nNum;
}
//本科生综合平均成绩、英语平均成绩----------------------------
void ResultsAverage()
{
//string strFilePathName;
StudentMessage* pStHead=NULL;
//strFilePathName=GetMessageFileName();
pStHead =MessageFromFile(strFilePathName3);
//
StudentMessage* pStCur=NULL;
pStCur=pStHead;
float fAverage=0;
float fCSum=0; //综合成绩和
float fESum=0; //英语成绩和
int nCount=0;
if(pStHead==NULL)
return;
do
{
if(pStCur->fEnglishResults)
{
fCSum=fCSum+pStCur->fComprehensive;
fESum=fESum+pStCur->fEnglishResults;
nCount++;
}
pStCur=pStCur->pNext;
}while(pStCur!=NULL);
Display(pStHead,0,0);
cout<<"综合平均成绩:"<<setprecision(3)<<fCSum/nCount<<endl;
cout<<"英语平均成绩:"<<setprecision(3)<<fESum/nCount<<endl;
}
//研究生按论文数量排序-----------------------------------------
//nAscending==1:升序
//nAscending==0:降序
void nThesisCountSort(int nAscending)
{
//string strFilePathName;
StudentMessage* pStHead=NULL;
//strFilePathName=GetMessageFileName();
pStHead =MessageFromFile(strFilePathName3);
//
StudentMessage*pStMax,*pStMaxPrev;
StudentMessage*pStCur,*pStCurPrev;
StudentMessage*pStSort=NULL;
//
if(pStHead==NULL||pStHead->pNext==NULL)
return;
while(pStHead!=NULL)
{
pStMaxPrev=NULL;
pStMax =pStHead;
pStCurPrev=pStHead;
pStCur =pStCurPrev->pNext;
//查找最大值
while(pStCur!=NULL)
{
if(pStCur->nThesisCount>pStMax->nThesisCount)
{
pStMax =pStCur;
pStMaxPrev=pStCurPrev;
}
pStCurPrev =pStCur;
pStCur=pStCur->pNext;
};
//将最大(最小)节点从链表pRsHead摘出
if(pStMaxPrev==NULL) //第一个节点
pStHead=pStHead->pNext;
else if(pStMax->pNext==NULL) //最后节点
pStMaxPrev->pNext=NULL;
else //中间节点
pStMaxPrev->pNext=pStMax->pNext;
pStMax->pNext =NULL;
//将最大(最小)节点插入排序链表pRsSort的前端
if(pStSort==NULL)
{
pStSort=pStMax;
}
else
{
if(nAscending ==1) //升序,次大值插入排序链表首部
{
pStMax->pNext=pStSort;
pStSort=pStMax;
}
else //降序,插入排序链表尾部
{
pStCur=pStSort;
while(pStCur->pNext!=NULL)
pStCur=pStCur->pNext;
//次大值连接到尾部
pStCur->pNext=pStMax;
}
}
}
MessageToFile(strFilePathName3,pStSort,0);
Display(pStSort,0,1);
}
//系统菜单--------------------------------------------------
int MenuMain()
{
int nChoice=0;
do
{
cout<<endl;
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<<"0: 退出"<<endl;
cout<<"请选择功能:";
cin>>nChoice;
}while(nChoice<0||nChoice>8);
return nChoice;
}
int MenuInquiry()
{
int nChoice=0;
do
{
cout<<endl;
cout<<" 成绩查询 "<<endl;
cout<<"1: 显示本科生成绩"<<endl;
cout<<"2: 显示研究生成绩"<<endl;
cout<<"0: 退出"<<endl<<endl;
cout<<"请选择:";
cin>>nChoice;
}while(nChoice<0||nChoice>4);
return nChoice;
}
//信息查询-----------------------------------------------------
bool MessageInquiry()
{
int nChoice=0;
/*
string strFilePathName;
StudentMessage* pStHead=NULL;
//
strFilePathName=GetMessageFileName();
pStHead=MessageFromFile(strFilePathName);
if(pStHead==NULL)
return false;
*/
do
{
nChoice=MenuInquiry();
switch(nChoice)
{
case 0:
break;
case 1: //显示本科生信息,
MessageBrowser(0); //0表示本科生
break;
case 2:
MessageBrowser(1); //1表示研究生
break;
default:
cout<<"输入错误!";
break;
}
}while(nChoice!=0);
//FreeMem(pStHead);
return true;
}
//--------------------------------------
//-------------系统主程序---------------
//--------------------------------------
int main()
{
strFilePathName3=GetMessageFileName();
int nChoice=0;
int nNd=0;
do
{
nChoice=MenuMain();
switch(nChoice)
{
case 0:
break;
case 1:
StudentMessageInput(0);
break;
case 2:
InquiryByNo();
break;
case 3:
StudentMessageInput(1);
break;
case 4:
MessageDelete();
break;
case 5:
ResultsAverage();
break;
case 6:
//nThesisCountSort(1);
cout<<"0 降序\n"<<"1 升序\n"<<endl;
cin>>nNd;
if(nNd==0||nNd==1)
nThesisCountSort(nNd);
else
cout<<"输入错误!"<<endl;
break;
case 7:
MessageInquiry();
break;
case 8:
InquiryByName();
break;
default:
cout<<"选择错误!"<<endl;
}
}while(nChoice!=0);
return 0;
}