CallRoll文件夹下为每次电子点名得到的txt文件,每个txt文件格式如下:
应到人数:11
实到人数:9
已到学生:学生三;学生四;学生五;学生六;学生七;学生八;学生九;222;111;
未到学生:学生一;学生二;
需要得到的结果:将多个txt文件中学生的考勤情况统计出来
程序如下:
首先定义一个结构体:
//---------定义所有学生点到次数的结构体----------
struct stuAttendance
{
char attendanceName[20]; //每个学生姓名
int attendanceTimes; //学生点到次数 点到+1,未到+0
};
接下来是具体的实现过程:
CString sStudent;
CString sStuTemp; //保存取出应到学生代码中的学生信息
CString sStudentName; //当前班级的学生名单字符串,格式如:学生一;学生二;学生三;学生四;学生五;学生六;学生七;学生八;学生九;222;111;
char sStudentStr[20]; //当前班级的学生名单数组
CString gAbsentStudent; //将CallRoll文件中所有未到学生字符串连接成一个总的未到学生字符串
CString gPresentStudent; 将CallRoll文件中所有已到学生字符串连接成一个总的已到学生字符串
int nStudent; //当前班级中的学生个数
int flag = 0;
//结构体
stuAttendance FinalAttendance[20]; //定义有20个学生,最终得到的考勤结果
CFileFind finder;
BOOL bWorking = finder.FindFile(".//CallRoll//*.txt"); //读取当前工程目录下的CallRoll文件夹中的txt文件
while (bWorking) //当学生签到次数等于bWorking时为全勤
{
int nAbsent = 0;
CString sAbsentStudent,sPresentStudent; //取出已到学生:和未到学生:后的字符串
bWorking = finder.FindNextFile();
MessageBox((LPCTSTR)finder.GetFilePath());
FILE *fp = fopen( (LPCTSTR)finder.GetFilePath(), "rb"); //注意这里rb指定二进制方式读
char szTemp[4096];
int pos,pos2,pos3;
memset(szTemp, 0, sizeof(szTemp));
fflush(fp);
int nReadData = fread(szTemp, 1, 4096, fp);
sStudent = szTemp;
//取出CallRoll文件中"未到学生:"后的字符串
sAbsentStudent=sStudent;
for (int absent = 0; absent < 4; absent++)
{
pos = sAbsentStudent.Find(":");
sAbsentStudent = sAbsentStudent.Right(sAbsentStudent.GetLength() - pos - 1);
}
pos2 = sAbsentStudent.Find("/r");
sAbsentStudent = sAbsentStudent.Left(pos2);
gAbsentStudent += sAbsentStudent;
//MessageBox(sAbsentStudent);
//取出CallRoll文件中"已到学生: "后的字符串
sPresentStudent = sStudent;
for (int present = 0; present < 3; present++)
{
pos = sPresentStudent.Find(":");
sPresentStudent = sPresentStudent.Right(sPresentStudent.GetLength() - pos - 1);
}
pos = sPresentStudent.Find("/n");
sPresentStudent = sPresentStudent.Left(pos);
//MessageBox(sPresentStudent);
pos3 = sPresentStudent.Find("/r");
sPresentStudent = sPresentStudent.Left(pos3);
gPresentStudent += sPresentStudent;
if (flag == 0)
{
//从CallRoll文件中取出应到人数nStudent
sStuTemp = sStudent; //拷贝sStudent中的内容保存到sStuTemp中,避免取出nStudent值时修改sStudent的值
pos = sStuTemp.Find(":");
sStuTemp = sStuTemp.Right(sStuTemp.GetLength() - pos - 1);
pos = sStuTemp.Find("/n");
sStuTemp = sStuTemp.Left(pos);
//MessageBox(sStuTemp);
nStudent = atoi(sStuTemp);
sStudentName = sAbsentStudent + sPresentStudent; //取出当前班级的学生名单,格式如:学生一;学生二;学生三;学生四;学生五;学生六;学生七;学生八;学生九;222;111;
//删掉当前班级的学生名单中的;号
for (int i = 0; i < nStudent; i++)
{
pos = sStudentName.Find(";");
sprintf(sStudentStr, "%s", sStudentName.Left(pos)); //cstring转char[]
strcpy(FinalAttendance[i].attendanceName,sStudentStr);
// FinalAttendance[i].attendanceName = sStudentStr;
sStudentName = sStudentName.Right(sStudentName.GetLength() - pos - 1);
}
flag =1;
}
}
int bAttendance = 0; //非-1表示已到,-1表示未到
//计算每个学生签到次数
for (int i = 0; i < nStudent; i++)
{
FinalAttendance[i].attendanceTimes = 0;
CString gTemp = gPresentStudent;
bAttendance = gTemp.Find(FinalAttendance[i].attendanceName); //当bAttendance=-1时,表示未找到
// while(gTemp.Find(FinalAttendance[i].attendanceName) != -1)
while(bAttendance != -1)
{
FinalAttendance[i].attendanceTimes++;
gTemp = gTemp.Right(gTemp.GetLength() - bAttendance - 1);
bAttendance = gTemp.Find(FinalAttendance[i].attendanceName);
}
}