通過一個月的努力,終於把數據結構技能考試系統用C++的語言實現(其中有C語言的穿插),系統的最大優點是可以檢測學生答題時是否插入了U盤,打開了word及記事本等輔助工具。此系統分為兩部分,一部分是學生端,一部分是教師端。
學生端主要是學生輸入學號及姓名(對此進行檢測),根據學號的後四位對應的ASCII碼模8求值,達到抽題的效果(也可適當改進改為IP讀題),在題庫中抽取兩道題,隨機答一道題即可,在完成作答後選擇所作的試題,避免了選題後不會做的情況。抽題時顯示倒計時,時間為60分鐘,如若超時,允許的最大期限為20分鐘,答題結束後可自動將程序及加密的學生信息發送至教師端。
教師端的功能是獲取學生的文件,依次打開它的cpp和信息文件,並錄入成績,最後生成學生成績表格。減少了需要去學生端看程序,錄成績的麻煩。
系統的部分注意事項如下:
學生端:
#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; }
如若有什麼問題,歡迎大家指出。