通过一个月的努力,终于把数据结构技能考试系统用C++的语言实现(其中有C语言的穿插),系统的最大优点是可以检测学生答题时是否插入了U盘,打开了word及记事本等辅助工具。此系统分为两部分,一部分是学生端,一部分是教师端。
学生端主要是学生输入学号及姓名(对此进行检测),根据学号的后四位对应的ASCII码模8求值,达到抽题的效果(也可适当改进改为IP读题),在题库中抽取两道题,随机答一道题即可,在完成作答后选择所作的试题,避免了选题后不会做的情况。抽题时显示倒计时,时间为60分钟,如若超时,允许的最大期限为20分钟,答题结束后可自动将程序及加密的学生信息发送至教师端。
教师端的功能是获取学生的文件,依次打开它的cpp和信息文件,并录入成绩,最后生成学生成绩表格。减少了需要去学生端看程序,录成绩的麻烦。
系统的部分注意事项如下:
- 需要将文件放在D盘的数据结构技能考试文件夹中,文件夹中包含一个名为Ti的文件夹及xuehao,xingming的txt文本,Ti文件夹中放试题,命名格式为1.txt,2.txt等,xuehao放学生的学号,姓名放学生的姓名。
- 学生端生成的cpp文件,需要手动打开,如果期间重新打开,倒计时重新开始。
- 学生端如果检测到U盘,word等打开则屏蔽题目,合法后才能继续进行考试。
- 教师端需要把D盘的数据结构技能考试文件夹中的新建考生信息文件,并将其改为共享模式。
- 教师端每次读取的学生数量一旦固定后,系统将依次从头至尾读取相应的个数,不管上传的时间。
学生端:
#include<stdio.h> #include<stdlib.h> #include<iostream> #include<math.h> #include<time.h> #include<string.h> #include <fstream> #include<conio.h> #include<Windows.h> # define NORMAL_SIZ BUFSIZ #define CHMSK_KEY 0xa5 char buf[NORMAL_SIZ]; using namespace std; //在屏幕上显示试题内容 int duquwenben(string a) { FILE *fp; fp=fopen(a.c_str(),"r"); char buf[1024]; while((fgets(buf,1024,fp))!=NULL) { printf("%s",buf); } printf("\n"); return 0; } //读取驱动状态 int GetDriverInfo(LPSTR szDrive) { UINT uDriverType; uDriverType = GetDriveType(szDrive); if(uDriverType==DRIVE_REMOVABLE) return 1; else return 0; } //判断是否有U盘插入 int checkUdisk() { CHAR szLogicDriveStrings[1024]; PCHAR szDrive; GetLogicalDriveStrings(1023,szLogicDriveStrings); szDrive = (PCHAR)szLogicDriveStrings; for(int i=0;i<7;i++) { if(GetDriverInfo(szDrive)) return 1; szDrive += (lstrlen(szDrive)+1); } return 0; } //判断是否打开word,PPT及记事本 int checkTask() { string temp1,temp2,temp3; temp1="tasklist | find "; temp2=temp1+"\"WINWORD\" "+"> 1.txt"; system(temp2.c_str()); temp2=temp1+"\"POWERPNT\" "+">> 1.txt"; system(temp2.c_str()); temp2=temp1+"\"note\" "+">> 1.txt"; system(temp2.c_str()); ifstream test; test.open("1.txt"); while(!test.eof()) { test>>temp3; if(temp3.length()>3) { return 1; break; } } test.close(); return 0; } //将学生的相关内容存储到xinxi文本文档中 void xinxi(){ FILE *fp=fopen("d:\\数据结构技能考试\\xinxi.txt","w+"); fprintf(fp,"%s","d:\\数据结构技能考试\\"); fclose(fp); } //登录界面并判断是否符合信息 void denglu1(char b[]){ FILE *fp=fopen("d:\\数据结构技能考试\\xinxi.txt","w+"); FILE *fq=fopen("d:\\数据结构技能考试\\xingming.txt","r"); char m[4],ch,s[100]; int i=0,k=0,n,x=0,y,len; // m1[0]='\n'; printf("请输入姓名:"); for(int v=0;v<3&&k==0;v++){ gets(b); fclose(fq); FILE *fq=fopen("d:\\数据结构技能考试\\xingming.txt","r"); while(fgets(s,100,fq) != NULL){ len = strlen(s); s[len-1] = '\0'; if(strcmp(b,s)==0){ fputs(b,fp); k=1; break; } } if(k==0&&v<2) printf("请重新输入:"); } fclose(fp); fclose(fq); if(k==0) exit(0); } //登录学号界面并判断是否符合信息 void denglu2(char c[]){ FILE *fp=fopen("d:\\数据结构技能考试\\xinxi.txt","a+"); FILE *fq=fopen("d:\\数据结构技能考试\\xuehao.txt","r"); char m[4],ch,s[100]; int i=0,k=0,n,x=0,y,len; printf("请输入学号:"); for(int v=0;v<3&&k==0;v++){ gets(c); fclose(fq); FILE *fq=fopen("d:\\数据结构技能考试\\xuehao.txt","r"); while(fgets(s,100,fq) != NULL){ len = strlen(s); s[len-1] = '\0'; if(strcmp(c,s)==0){ fprintf(fp,"\n"); fputs(c,fp); k=1; break; } } if(k==0&&v<2) printf("请重新输入:"); } fclose(fp); fclose(fq); if(k==0) exit(0); } //根据学生的学号抽题 int chuti(int a ){ int b; a=a%8; b=a+10; FILE *fp=fopen("d:\\数据结构技能考试\\xinxi.txt","a+"); string tempIdd; string tempId="d:\\数据结构技能考试\\Ti\\1.txt"; fprintf(fp,"\n"); fprintf(fp,"%s","学生抽到的试题是:"); printf("\n抽到的试题是:第%d题和第%d题\n",a+1,b+1); fprintf(fp,"%s","第"); fprintf(fp,"%d",a+1); fprintf(fp,"%s","题和第"); fprintf(fp,"%d",b+1); fprintf(fp,"%s","题"); fprintf(fp,"\n"); switch(a){ case 0: tempId="d:\\数据结构技能考试\\Ti\\1.txt"; break; case 1: tempId="d:\\数据结构技能考试\\Ti\\2.txt";break; case 2: tempId="d:\\数据结构技能考试\\Ti\\3.txt";break; case 3: tempId="d:\\数据结构技能考试\\Ti\\4.txt";break; case 4: tempId="d:\\数据结构技能考试\\Ti\\5.txt";break; case 5: tempId="d:\\数据结构技能考试\\Ti\\6.txt";break; case 6: tempId="d:\\数据结构技能考试\\Ti\\7.txt";break; case 7: tempId="d:\\数据结构技能考试\\Ti\\8.txt";break; case 8: tempId="d:\\数据结构技能考试\\Ti\\9.txt";break; case 9: tempId="d:\\数据结构技能考试\\Ti\\10.txt";break; case 10: tempId="d:\\数据结构技能考试\\Ti\\11.txt";break; case 11: tempId="d:\\数据结构技能考试\\Ti\\12.txt";break; case 12: tempId="d:\\数据结构技能考试\\Ti\\13.txt";break; case 13: tempId="d:\\数据结构技能考试\\Ti\\14.txt";break; case 14: tempId="d:\\数据结构技能考试\\Ti\\15.txt";break; case 15: tempId="d:\\数据结构技能考试\\Ti\\16.txt";break; case 16: tempId="d:\\数据结构技能考试\\Ti\\17.txt";break; case 17: tempId="d:\\数据结构技能考试\\Ti\\18.txt";break; } duquwenben(tempId); printf("*********************************************************** \n"); switch(b){ case 0: tempIdd="d:\\数据结构技能考试\\Ti\\1.txt"; break; case 1: tempIdd="d:\\数据结构技能考试\\Ti\\2.txt";break; case 2: tempIdd="d:\\数据结构技能考试\\Ti\\3.txt";break; case 3: tempIdd="d:\\数据结构技能考试\\Ti\\4.txt";break; case 4: tempIdd="d:\\数据结构技能考试\\Ti\\5.txt";break; case 5: tempIdd="d:\\数据结构技能考试\\Ti\\6.txt";break; case 6: tempIdd="d:\\数据结构技能考试\\Ti\\7.txt";break; case 7: tempIdd="d:\\数据结构技能考试\\Ti\\8.txt";break; case 8: tempIdd="d:\\数据结构技能考试\\Ti\\9.txt";break; case 9: tempIdd="d:\\数据结构技能考试\\Ti\\10.txt";break; case 10: tempIdd="d:\\数据结构技能考试\\Ti\\11.txt";break; case 11: tempIdd="d:\\数据结构技能考试\\Ti\\12.txt";break; case 12: tempIdd="d:\\数据结构技能考试\\Ti\\13.txt";break; case 13: tempIdd="d:\\数据结构技能考试\\Ti\\14.txt";break; case 14: tempIdd="d:\\数据结构技能考试\\Ti\\15.txt";break; case 15: tempIdd="d:\\数据结构技能考试\\Ti\\16.txt";break; case 16: tempIdd="d:\\数据结构技能考试\\Ti\\17.txt";break; case 17: tempIdd="d:\\数据结构技能考试\\Ti\\18.txt";break; } duquwenben(tempIdd); if(checkUdisk()){ printf("禁止插入u盘,请拔下后重试\n"); while(checkUdisk()) Sleep(1); } fclose(fp); // system(f); return 0; } //如果期间有异常会重新显示题目 int chongchuti(int a){ int b; a=a%8; b=a+10; string tempId,tempIdd; tempId="d:\\数据结构技能考试\\Ti\\1.txt"; printf("\n抽到的试题是:第%d题和第%d题\n",a+1,b+1); switch(a){ case 0: tempId="d:\\数据结构技能考试\\Ti\\1.txt"; break; case 1: tempId="d:\\数据结构技能考试\\Ti\\2.txt";break; case 2: tempId="d:\\数据结构技能考试\\Ti\\3.txt";break; case 3: tempId="d:\\数据结构技能考试\\Ti\\4.txt";break; case 4: tempId="d:\\数据结构技能考试\\Ti\\5.txt";break; case 5: tempId="d:\\数据结构技能考试\\Ti\\6.txt";break; case 6: tempId="d:\\数据结构技能考试\\Ti\\7.txt";break; case 7: tempId="d:\\数据结构技能考试\\Ti\\8.txt";break; case 8: tempId="d:\\数据结构技能考试\\Ti\\9.txt";break; case 9: tempId="d:\\数据结构技能考试\\Ti\\10.txt";break; case 10: tempId="d:\\数据结构技能考试\\Ti\\11.txt";break; case 11: tempId="d:\\数据结构技能考试\\Ti\\12.txt";break; case 12: tempId="d:\\数据结构技能考试\\Ti\\13.txt";break; case 13: tempId="d:\\数据结构技能考试\\Ti\\14.txt";break; case 14: tempId="d:\\数据结构技能考试\\Ti\\15.txt";break; case 15: tempId="d:\\数据结构技能考试\\Ti\\16.txt";break; case 16: tempId="d:\\数据结构技能考试\\Ti\\17.txt";break; case 17: tempId="d:\\数据结构技能考试\\Ti\\18.txt";break; } duquwenben(tempId); printf("*********************************************************** \n"); switch(b){ case 0: tempIdd="d:\\数据结构技能考试\\Ti\\1.txt"; break; case 1: tempIdd="d:\\数据结构技能考试\\Ti\\2.txt";break; case 2: tempIdd="d:\\数据结构技能考试\\Ti\\3.txt";break; case 3: tempIdd="d:\\数据结构技能考试\\Ti\\4.txt";break; case 4: tempIdd="d:\\数据结构技能考试\\Ti\\5.txt";break; case 5: tempIdd="d:\\数据结构技能考试\\Ti\\6.txt";break; case 6: tempIdd="d:\\数据结构技能考试\\Ti\\7.txt";break; case 7: tempIdd="d:\\数据结构技能考试\\Ti\\8.txt";break; case 8: tempIdd="d:\\数据结构技能考试\\Ti\\9.txt";break; case 9: tempIdd="d:\\数据结构技能考试\\Ti\\10.txt";break; case 10: tempIdd="d:\\数据结构技能考试\\Ti\\11.txt";break; case 11: tempIdd="d:\\数据结构技能考试\\Ti\\12.txt";break; case 12: tempIdd="d:\\数据结构技能考试\\Ti\\13.txt";break; case 13: tempIdd="d:\\数据结构技能考试\\Ti\\14.txt";break; case 14: tempIdd="d:\\数据结构技能考试\\Ti\\15.txt";break; case 15: tempIdd="d:\\数据结构技能考试\\Ti\\16.txt";break; case 16: tempIdd="d:\\数据结构技能考试\\Ti\\17.txt";break; case 17: tempIdd="d:\\数据结构技能考试\\Ti\\18.txt";break; } duquwenben(tempIdd); return 0; } //生成学生信息的文档将会加密 void jiami(){ FILE *fp = fopen("d:\\数据结构技能考试\\xinxi.txt", "rb+"); int n; while ((n = fread(buf, 1, NORMAL_SIZ, fp)) > 0) { int i; for (i = 0; i < n; i++) { buf[i] ^= CHMSK_KEY; } if (fseek(fp, -n, SEEK_CUR) == -1) { perror("fseek"); } n = fwrite(buf, 1, n, fp); fflush(fp);//如果不加这句,那么文件大小如果小于库函数缓冲(默认是BUFSIZ大小)时实际上面的写操作并没写进去,从而导致下一次read还是成功,因此程序不会退出 buf[0] = 0; } fclose(fp); } //倒计时,时间为1小时 void daojishi(int a,int m[0],int sec[0]){ m[0]=59,sec[0] = 59; printf("\n"); while(m[0]>=0){ sec[0] = 59; while(sec[0] > 0) { if(_kbhit()) break; printf("\r%2d:%2d",m[0],sec[0]); Sleep(1000); sec[0]--; if(sec[0]%10==0){ if(checkUdisk()){ system("cls"); while(checkUdisk()){ Sleep(1); printf("禁止插入u盘,请拔下后重试\n"); system("cls"); } chongchuti(a); printf(" 剩余时间"); } if(checkTask()) { system("cls"); while(checkTask()) { Sleep(1); printf("禁止使用word、ppt、txt文件,请关闭后重新登陆\n"); system("cls"); } chongchuti(a); printf(" 剩余时间"); } } } if(_kbhit()) break; // printf("***%d\n",m[0]); // printf("***%d\n",sec[0]); if(m[0]==0&&sec[0]==1) break; m[0]--; } /* if(sec > 0) { system("cls"); //print_jiayou(); } else printf("\n超时啦!");*/ // getchar(); if(m[0]!=0&&sec[0]!=1) getchar(); } //如若超过一小时,最多允许20分钟超时 void chaoshi(int a,int m1[0],int sec1[0]){ m1[0]=19,sec1[0] = 59; printf("\n"); while(m1[0]>=0){ sec1[0] = 59; while(sec1[0] > 0) { if(_kbhit()) break; printf("\r%2d:%2d",m1[0],sec1[0]); printf(" 超时时间\n"); Sleep(1000); sec1[0]--; if(sec1[0]%10==0){ if(checkUdisk()){ system("cls"); while(checkUdisk()){ Sleep(1); printf("禁止插入u盘,请拔下后重试\n"); system("cls"); } chongchuti(a); printf(" 超时时间"); } if(checkTask()) { system("cls"); while(checkTask()) { Sleep(1); printf("禁止使用word、ppt、txt文件,请关闭后重新登陆\n"); system("cls"); } chongchuti(a); printf(" 超时时间"); } } } if(_kbhit()) break; // printf("***%d\n",m[0]); // printf("***%d\n",sec[0]); if(m1[0]==0&&sec1[0]==1) break; m1[0]--; } /* if(sec > 0) { system("cls"); //print_jiayou(); } else printf("\n超时啦!");*/ // getchar(); if(m1[0]!=0&&sec1[0]!=1) getchar(); } int main(){ char a[10000]; int b[10],c[2]; char d[4],e[14]; char g[20]; char f[12]; char s[25]; int n,x=0,l; int m[1],sec[1]; int m1[1],sec1[1]; xinxi(); FILE *fx=fopen("d:\\数据结构技能考试\\xinxi.txt","r+"); fgets(f,25,fx); fclose(fx); /*检查是否有U盘及相关文件打开*/ if(checkUdisk()){ printf("禁止插入u盘,请拔下后重试\n"); while(checkUdisk()) Sleep(1); } if(checkTask()){ printf("禁止使用word、ppt、txt文件,请关闭后重试\n"); while(checkTask()) Sleep(1); } /*登录界面*/ system("cls"); denglu1(e); denglu2(d); int mg=d[10]+d[11]+d[12]+d[13];//获取学生的学号 //生成学生学号的cpp文件 FILE *fc=fopen("d:\\数据结构技能考试\\xinxi.txt","r+"); if(checkUdisk()){ printf("禁止插入u盘,请拔下后重试\n"); while(checkUdisk()) Sleep(1); } fgets(s,25,fc);/*用fgets读第一行到数组s中*/ n=strlen(s); x +=n; fseek(fc,x+1,SEEK_SET);/*将文件指针移到下一行*/ fgets(s,25,fc);/*用fgets读第二行到数组s中*/ for(int v=0;v<15;v++){ f[20+v]=s[v]; } f[34]='.'; f[35]='c'; f[36]='p'; f[37]='p'; f[38]='\0'; fflush(stdin); FILE *mv=fopen(f,"w+"); fclose(mv); fclose(fc); if(checkUdisk()){ printf("禁止插入u盘,请拔下后重试\n"); while(checkUdisk()) Sleep(1); } chuti(mg);//抽题 /*倒计时开始*/ printf("\n考试开始,时间为60分钟,现剩余:"); daojishi(mg,m,sec); m[0]=59-m[0]; sec[0]=59-sec[0]; if(m[0]==0&&sec[0]==58)//如果倒计时结束还未停止,则自动记录超时时间 chaoshi(mg,m1,sec1); else{ m1[0]=19; sec1[0]=59; } if(sec[0]==59){ m[0]++; sec[0]=0; } m1[0]=19-m1[0]; sec1[0]=59-sec1[0]; if(sec1[0]==59){ m1[0]++; sec1[0]=0; } fflush(stdin); //输入选择的题号 FILE *fg=fopen("d:\\数据结构技能考试\\xinxi.txt","a+"); printf("请输入选择的题号:"); scanf("%d",&l); while(l!=mg%8+1&&l!=mg%8+11){ printf("请输入选择的题号:"); scanf("%d",&l); } fprintf(fg,"%s","学生选择的题号是:"); fprintf(fg,"%d",l); fprintf(fg,"\n"); fprintf(fg,"%s","学生做题时间为:"); fprintf(fg,"%d",m[0]); fprintf(fg,"%s",":"); fprintf(fg,"%d",sec[0]); fprintf(fg,"\n"); fprintf(fg,"%s","学生做题超时时间为:"); fprintf(fg,"%d",m1[0]); fprintf(fg,"%s",":"); fprintf(fg,"%d",sec1[0]); fclose(fg); //上传到局域网的教室端 string teachIp="\\\\172.17.1.41\\考生信息"; string sss(f); string dosStr2="copy "+sss+" "+teachIp; if(system(dosStr2.c_str())!=0){ printf("上传失败,请手动上传"); puts(f); } else printf("上传成功\n"); f[34]='.'; f[35]='t'; f[36]='x'; f[37]='t'; f[38]='\0'; jiami();//生成学生信息文件并加密 rename( "d:\\数据结构技能考试\\xinxi.txt",f); fclose(fc); string ddd(f); string dosStr="copy "+ddd+" "+teachIp; if(system(dosStr.c_str())!=0){//上传失败,提示手动上传及文件的位置 printf("上传失败,请手动上传"); puts(f); } else printf("上传成功\n"); Sleep(30000); return 0; }
教师端:
#include<stdio.h> #include<string.h> #include<io.h> #include <stdlib.h> #include<time.h> #include<windows.h> #include<iostream> #include<conio.h> #include<string.h> #define NORMAL_SIZ BUFSIZ #define CHMSK_KEY 0xa5 using namespace std; char buf[NORMAL_SIZ]; #define number 300 //导入的行数 //读取文本内容 int duquwenben(string a) { FILE *fp; fp=fopen(a.c_str(),"r"); char buf[1024]; while((fgets(buf,1024,fp))!=NULL) { printf("%s",buf); } printf("\n"); return 0; } //将学生端的信息解密 void jiemi(char a[]){ FILE *fp = fopen(a,"rb+"); int n; while ((n = fread(buf, 1, NORMAL_SIZ, fp)) > 0) { int i; for (i = 0; i < n; i++) { buf[i] ^= CHMSK_KEY; } if (fseek(fp, -n, SEEK_CUR) == -1) { perror("fseek"); } n = fwrite(buf, 1, n, fp); fflush(fp);//如果不加这句,那么文件大小如果小于库函数缓冲(默认是BUFSIZ大小)时实际上面的写操作并没写进去,从而导致下一次read还是成功,因此程序不会退出 buf[0] = 0; } fclose(fp); } //动态获取学生的个数,直到满足条件 int presencename(){ system("dir d:\\数据结构技能考试\\考生信息\\*.cpp /b > d:\\数据结构技能考试\\考生信息\\cpp.dat"); FILE *fp=fopen("d:\\数据结构技能考试\\考生信息\\cpp.dat","r"); char m[4],ch,s[100]; int i=0,k=0,n,x=0,y,len,b; string note="d:\\数据结构技能考试\\考生信息\\cpp.dat"; printf("请输入学生的个数:"); scanf("%d",&b); while(1){ if(_kbhit()) break; i=0; fclose(fp); system("dir d:\\数据结构技能考试\\考生信息\\*.cpp /b > d:\\数据结构技能考试\\考生信息\\cpp.dat"); FILE *fp=fopen("d:\\数据结构技能考试\\考生信息\\cpp.dat","r"); while(fgets(s,100,fp) != NULL){ len = strlen(s); s[len-1] = '\0'; i++; if(i>=b) break; } duquwenben(note); printf("现在的学生个数为:%d\n",i); if(i==b) break; Sleep(10000); system("cls"); } getchar(); return b; } //读取学生信息,依次打开.cpp和相关信息文件,并录入成绩 void read(int num){ /*将学生的信息的文件名放在一个txt文件中*/ system("dir d:\\数据结构技能考试\\考生信息\\*.cpp /b > d:\\数据结构技能考试\\考生信息\\cpp1.dat"); char str[50]={"d:\\数据结构技能考试\\考生信息\\"},str1[num][30],date[number][11],str2[50]; double price[number][6]; float z ; char f[40],m[1],n[15],v[7];; FILE *in,*fp,*fq; char ch; int j; in=fopen("d:\\数据结构技能考试\\考生信息\\cpp1.dat","r"); if(in==NULL){//如果生成的新文件失败,退出系统 printf("can't open the file999."); exit(0); } /*生成学生成绩的Excel文件,名字为学生成绩*/ fq=fopen("d:\\数据结构技能考试\\学生成绩.csv","w+"); fprintf(fq,"%s","姓名"); fprintf(fq,","); fprintf(fq,"%s","学号"); fprintf(fq,","); fprintf(fq,"%s","成绩"); fprintf(fq,"\n"); fclose(fq); for(int i=0;i<num;i++){ fflush(stdin); fq=fopen("d:\\数据结构技能考试\\学生成绩.csv","a+"); fscanf(in,"%s",&str1[i][0]); strcat(str,&str1[i][0]); system(str);//打开学生的cpp文件 for( j=0;str[j]!='\0';j++); strcpy(str2,str); str2[j-1]='t'; str2[j-2]='x'; str2[j-3]='t'; jiemi(str2); system(str2);//打开学生的txt文件 fflush(stdin); fp=fopen(str2,"r"); int k=0; fflush(stdin); fread(m,7,1,fp); m[6]='\0'; fflush(stdin); fprintf(fq,m);//写入学生的姓名 fflush(stdin); fclose(fq); fq=fopen("d:\\数据结构技能考试\\学生成绩.csv","a+"); fprintf(fq,","); fread(n,14,1,fp); n[14]='\0'; fprintf(fq,"’"); fprintf(fq,n);//写入学生学号 for(int i=0;i<number;i++){ fscanf(fp,"%s",&date[i][0]); for(j=0;j<6;j++) fscanf(fp,"%lf",&price[i][j]); } fclose(fp); fclose(fq); fflush(stdin); printf("请输入成绩:"); scanf("%f",&z); fq=fopen("d:\\数据结构技能考试\\学生成绩.csv","a+"); fprintf(fq,","); fprintf(fq," %f",z);//写入学生的成绩 fprintf(fq,"\n"); fclose(fq); strcpy(str,"d:\\数据结构技能考试\\考生信息\\"); } fclose(in); } int main(){ read(presencename());//自动获取文件,并录入 return 0; }
如若有什么问题,欢迎大家指出。