編譯環境:Visual C++ 6.0
結對同伴:02邬進納 http://home.cnblogs.com/u/fitfit/
估計用時:一周
開發時間:2015-04-06——2015-04-09
4個方向:
3.用戶答題結束以後,程序可以顯示用戶答題所用的時間
4.用戶可以選擇出題的個數,答題結束可以顯示用戶答錯的題目個數和答對的題目個數
5.用戶在第一次答題時,需要用戶輸入用戶名,用戶下次啟動後,程序需要記住用戶前一次輸入的用戶名
8.程序可以設置皮膚功能,可以改變界面的顏色即可。
不足:
這個程序有很多不完善的地方,例如,當輸入的用戶是以前注冊過的用戶時,程序並沒有提示,而是再注冊一次。還有其他許多的不足之處。。。要完善這些對我來說不是一件容易的事情。有待完善。。。
總結:
這次的實驗是對我的一次大考驗。自己動手,發現問題和解決問題。並發現了許多自己的不足,平時沒掌握的知識在實踐中暴漏,經過不斷的思考,查閱書籍和上網查資料及上機運行,解決了大部分問題,還稍微有些小問題。本次編寫的小學四則運算練習軟件,它具有隨機出題、自動評分、自動排名,查看正確答案、錯題重做等功能,本系統功能強大(其實很多不足),在編程中,很多知識,幾乎是一片空白。不過後來通過網絡和參考許多別人的代碼才做了出來。。。
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<time.h> float A=0; int nu=0; int hourA,hourB,minA,minB; time_t start,end; struct Student { char name[21]; //姓名 char num[10]; //學號或編號 float avscore; }s[50]; //結構體數組,存儲學生的信息,在此初定為50,可改 void Savemessage() //保存學生輸入信息的函數 { FILE *fp,*fp1; //定義文件指針,//以下判斷文件打開與否 ,"a"方式打開則可向文件尾寫數據 if((fp=fopen("studentmessage.txt","wb+"))==NULL) //打開文件studentmessage.txt { printf("打開文件失敗\n"); exit(0);} if((fp1=fopen("TestResult.txt","a"))==NULL) //打開文件TestResult.txt { printf("打開文件失敗\n"); exit(0);} printf(" 輸入姓名:"); //以下為要學生輸入個人信息 scanf("%s",s[0].name); printf(" 輸入學號:"); scanf("%s",&s[0].num); fwrite(&s[0],sizeof(struct Student),1,fp); //向文件studentmessage.txt中寫入一條記錄,即剛剛輸入的學生信息 fprintf(fp1," 姓名:%s\n",s[0].name); //以下為向文件TestResult.txt中寫入剛剛輸入的學生信息 fprintf(fp1," 學號:%s\n",s[0].num); fclose(fp); //關閉文件studentmessage.txt fclose(fp1); system("cls"); //清屏 } void Judge() //判斷函數 {int i=0; FILE *fp; //文件指針//以下判斷文件打開與否 ,"r"為只讀打開方式 printf("\n\n\n"); printf(" **********************小學四則運算練習軟件*******************\n"); printf(" *-----------------------------------------------------------*\n"); printf(" *-----------------------------------------------------------*\n"); printf(" *************************************************************\n"); printf(" *----------------------------注 冊-----------------------*\n"); printf(" *-----------------------------------------------------------*\n"); printf(" *----------------------------輸入姓名-----------------------*\n"); printf(" *-----------------------------------------------------------*\n"); printf(" *----------------------------輸入學號-----------------------*\n"); printf(" *-----------------------------------------------------------*\n\n\n"); if((fp=fopen("studentmessage.txt","r"))==NULL) //以下判斷文件打開與否 "a"方式打開則可向文件尾寫數據//打開文件studentmessage.txt { fp=fopen("studentmessage.txt","w+"); //如果沒有studentmessage.txt文件,則新建此文件,"w+"打開方式為新建一個文件 printf("無文件記錄,已新建.\n"); } while(!feof(fp)) //判斷是否到了文件尾 { fread(&s[i],sizeof(struct Student),1,fp); //一行一行從文件中讀出學生信息,保存在結構體數組student[]中 fscanf(fp,"\n"); //讀取換行符 i++; //i變量保存學生記錄個數 if(i==50) //當人數滿時即50個人滿時,因為數組下標從0開始,所以當i為29時 { printf("人數已滿,你已無法測試.\n"); fclose(fp); exit(0); } } } void Addition(int number) //加法運算函數,number為題目數形參 { FILE *fp,*fp2,*fp3; if((fp=fopen("TestResult.txt","a"))==NULL) { printf("打開文件失敗\n"); exit(0);} if((fp2=fopen("failedResult.txt","a"))==NULL) {printf("打開文件失敗\n"); exit(0);} if((fp3=fopen("rightResult.txt","a"))==NULL) {printf("打開文件失敗\n"); exit(0);} int num1,num2,num3,num4,m,n,count1=0,count2=0; float average=0.0; //正確率變量,注意是float類型 srand(time(0)); //初始化隨機數,如果沒有此語句,則每次運行程序時的隨機數是一樣的 fprintf(fp," 加法測試:\n"); //向文件寫入 fprintf(fp," 被加數 + 加數 = 你的結果 正確結果 是否正確\n");//向文件寫入 { printf(" *************************************************************\n");/*選擇難度*/ printf(" *------------------------- 請選擇難度:------------------------*\n"); printf(" *------------------------- 1.簡 單 -------------------------*\n"); printf(" *------------------------- 2.一 般 -------------------------*\n"); printf(" *------------------------- 3.困 難 -------------------------*\n"); printf(" *-------------------------------------------------------------*\n\n\n"); printf("請選擇難度: "); scanf("%d",&m);system("cls"); //清屏 { if(m==1) n=10 ; /*將m的值轉化為對應的n值,從而使隨機函數出現一位,2位,3位,*/ if(m==2) n=100 ; else if(m==3) n=1000 ;} printf(" \n **************************************************************************\n\n"); for(int i=0;i<number;i++) /*小於測試題目數時,循環*/ { if(m==1) {num1=rand()%n; num2=rand()%n; } //產生一位隨機數,num1,num2 if(m==2) { num1=10+rand()%(n-10); //產生兩位隨機數 num1,num2 num2=10+rand()%(n-10); } if(m==3) { num1=100+rand()%(n-100); //產生三位隨機數 num1,num2 num2=100+rand()%(n-100); } num3=num1+num2; //num3保存正確結果 printf(" %d + %d = ",num1,num2); //在終端屏幕上輸出題目 scanf("%d",&num4); //你要輸入的計算結果 if(num3==num4) //正確結果與你計算的結果比較,正確的話 { fprintf(fp," %d + %d =\t\t%d\t\t%d\t√ \n",num1,num2,num4,num3);//將結果記錄到TestResult.txt中 count1++; } //變量count1記錄正確題目的個數 else //錯誤的話,即num1!=num2時 { fprintf(fp," %d + %d =\t\t%d\t\t%d\t× \n",num1,num2,num4,num3); //將結果記錄到TestResult.txt中 fprintf(fp2," %d + %d =\n",num1,num2,num4,num3); //將錯誤題記錄到failedResult.txt中 fprintf(fp3," %d + %d = %d \n",num1,num2,num3); //將錯誤題正確結果記錄到failedResult.txt中 } } } average=float(count1)/float(number); //計算正確率,注意int整型要轉換為float類型 fprintf(fp," 正確 %d 道,錯誤 %d 道,正確率為:%f\n\n",count1,count2,average); A=A+average*100; nu++; fclose(fp); fclose(fp3); fclose(fp2); } void Subtracter(int number) //減法運算函數,注釋與加法一樣 { FILE *fp,*fp2,*fp3; if((fp=fopen("TestResult.txt","a"))==NULL) { printf("打開文件失敗\n"); exit(0); } if((fp2=fopen("failedResult.txt","a"))==NULL) { printf("打開文件失敗\n"); exit(0); } if((fp3=fopen("rightResult.txt","a"))==NULL) { printf("打開文件失敗\n"); exit(0); } int num1,num2,num3,num4,count1=0,n,m,count2=0; float average=0.0; srand(time(0)); fprintf(fp," 減法測試:\n"); fprintf(fp," 被減數 - 減數 = 你的結果 正確結果 是否正確\n"); printf(" *************************************************************\n");/*選擇難度*/ printf(" *------------------------- 請選擇難度:------------------------*\n"); printf(" *------------------------- 1.簡 單 -------------------------*\n"); printf(" *------------------------- 2.一 般 -------------------------*\n"); printf(" *------------------------- 3.困 難 -------------------------*\n"); printf(" *-------------------------------------------------------------*\n\n\n"); printf("請選擇: "); scanf("%d",&m);system("cls"); //清屏 {if(m==1) n=10 ; if(m==2) n=100 ; else if(m==3) n=1000 ;} printf(" \n **************************************************************************\n\n"); for(int i=0;i<number;i++) {if(m==1) {num1=rand()%n; num2=rand()%n; } //產生一位隨機數,num1,num2 if(m==2) {num1=10+rand()%(n-10); //產生兩位隨機數 num1,num2 num2=10+rand()%(n-10);} if(m==3) {num1=100+rand()%(n-100); //產生三位隨機數 num1,num2 num2=100+rand()%(n-100);} num3=num1-num2; printf(" %d - %d = ",num1,num2); scanf("%d",&num4); if(num3==num4) { fprintf(fp," %d - %d =\t\t%d\t\t%d\t√ \n",num1,num2,num4,num3); count1++; } else { fprintf(fp," %d - %d =\t\t%d\t\t%d\t× \n",num1,num2,num4,num3); count2++; fprintf(fp2," %d - %d =\n",num1,num2,num4,num3); fprintf(fp3," %d - %d = %d \n",num1,num2,num3); } } average=float(count1)/float(number); fprintf(fp," 正確 %d 道,錯誤 %d 道,正確率為:%f\n\n",count1,count2,average); A=A+average*100; nu++; fclose(fp);fclose(fp2); fclose(fp3); } void Multiplication(int number)//乘法運算函數,注釋與加法一樣 { FILE *fp,*fp2,*fp3; if((fp=fopen("TestResult.txt","a"))==NULL) { printf("打開文件失敗\n"); exit(0); } if((fp2=fopen("failedResult.txt","a"))==NULL) { printf("打開文件失敗\n"); exit(0); } if((fp3=fopen("rightResult.txt","a"))==NULL) { printf("打開文件失敗\n"); exit(0); } int num1,num2,num3,num4,m,n,count1=0,count2=0; float average=0.0; srand(time(0)); fprintf(fp," 乘法測試:\n"); fprintf(fp," 被乘數 * 乘數 = 你的結果 正確結果 是否正確\n"); { printf(" *************************************************************\n");/*選擇難度*/ printf(" *------------------------- 請選擇難度:------------------------*\n"); printf(" *------------------------- 1.簡 單 -------------------------*\n"); printf(" *------------------------- 2.一 般 -------------------------*\n"); printf(" *------------------------- 3.困 難 -------------------------*\n"); printf(" *-------------------------------------------------------------*\n\n\n"); printf("請選擇: ");} scanf("%d",&m); system("cls"); //清屏 {if(m==1) n=10 ; if(m==2) n=100 ; else if(m==3) n=1000 ;} printf(" \n **************************************************************************\n\n"); for(int i=0;i<number;i++) {if(m==1) {num1=rand()%n; num2=rand()%n; } if(m==2) {num1=10+rand()%(n-10); num2=10+rand()%(n-10);} if(m==3) { num1=100+rand()%(n-100); num2=100+rand()%(n-100); } num3=num1*num2; printf(" %d * %d = ",num1,num2); scanf("%d",&num4); if(num3==num4) { fprintf(fp," %d * %d =\t\t%d\t\t%d\t√\n",num1,num2,num4,num3); count1++; } else { fprintf(fp," %d * %d =\t\t%d\t\t%d\t×\n",num1,num2,num4,num3); count2++; fprintf(fp2," %d * %d =\n",num1,num2,num4,num3); fprintf(fp3," %d * %d = %d \n",num1,num2,num3); } } average=float(count1)/float(number); fprintf(fp," 正確 %d 道,錯誤 %d 道,正確率為:%f\n\n",count1,count2,average); A=A+average*100; nu++; fclose(fp); fclose(fp2); fclose(fp3); } void Division(int number) // 和加法運算函數注釋一樣 { FILE *fp,*fp2,*fp3; if((fp=fopen("TestResult.txt","a"))==NULL) { printf("打開文件失敗\n"); exit(0); } if((fp2=fopen("failedResult.txt","a"))==NULL) { printf("打開文件失敗\n"); exit(0); } if((fp3=fopen("rightResult.txt","a"))==NULL) { printf("打開文件失敗\n"); exit(0); } int num1,num2,m,n,count1=0,count2=0; float num3,num4,average; //正確率變量,注意是float類型 srand(time(0)); //初始化隨機數,如果沒有此語句,則每次運行程序時的隨機數是一樣的 fprintf(fp," 加法測試:\n"); //向文件寫入 fprintf(fp," 除數數/被除數= 你的結果 正確結果 是否正確\n");//向文件寫入 { printf(" *************************************************************\n");/*選擇難度*/ printf(" *------------------------- 請選擇難度:------------------------*\n"); printf(" *------------------------- 1.簡 單 -------------------------*\n"); printf(" *------------------------- 2.一 般 -------------------------*\n"); printf(" *------------------------- 3.困 難 -------------------------*\n"); printf(" *-------------------------------------------------------------*\n\n\n"); printf("請選擇:"); scanf("%d",&m);system("cls"); //清屏 {if(m==1) n=10 ; if(m==2) n=100 ; else if(m==3) n=1000 ;} printf(" \n **************************************************************************\n\n"); printf(" 請保留保留小數點後一位 \n"); for(int i=0;i<number;i++) //小於測試題目數時,循環 {if(m==1) num1=rand()%n; if(m==2) num1=10+rand()%(n-10); if(m==3) num1=100+rand()%(n-100); num2=n/10+rand()%(n-n/10); //產生不等於零的隨機數num3 num3=(float)(num1)/(float)(num2); //num3保存正確結果 printf(" %d / %d = ",num1,num2); //在終端屏幕上輸出題目 scanf("%f",&num4); //你要輸入的計算結果 num3=(int)(num3*10)/10.0; //實現保留小數點一位 if(num3==num4) //正確結果與你計算的結果比較,正確的話 {fprintf(fp," %d / %d =\t\t%.1f\t\t%.1f\t√ \n",num1,num2,num4,num3);//向文件中寫入 count1++; //變量count1記錄正確題目的個數 } else //錯誤的話,即num1!=num2時 {fprintf(fp," %d / %d =\t\t%.1f\t\t%.1f\t× \n",num1,num2,num4,num3); count2++; //變量count2記錄錯誤題目的個數 fprintf(fp2," %d / %d = \n",num1,num2); fprintf(fp3," %d / %d = %.1f \n",num1,num2,num3);}}} average=float(count1)/float(number); //計算正確率,注意int整型要轉換為float類型 fprintf(fp," 正確 %d 道,錯誤 %d 道,正確率為:%f\n\n",count1,count2,average); A=A+average*100; nu++; fclose(fp); fclose(fp2); fclose(fp3); } void rework() // 錯題重做 {int a; char ch; FILE *fp2,*fp3; if((fp2=fopen("failedResult.txt","a+"))==NULL) {printf("打開文件失敗\n"); exit(0);} if((fp3=fopen("rightResult.txt","a+"))==NULL) {printf("打開文件失敗\n"); exit(0);} printf("********************錯題重做***************************************\n"); while(!feof(fp2)) {ch=fgetc(fp2);printf("%c",ch); //讀取failedResult.txt中的錯題 if(ch=='=') scanf("%d",&a);} //輸入答案 fp2=fopen("failedResult.txt","w"); //清空之前數據 fclose(fp2); printf("========小朋友請查看正確答案===========================================\n"); while(!feof(fp3)) { ch=fgetc(fp3);printf("%c",ch);} //讀取rightResult.txt中的錯題的答案 fclose(fp3);fp3=fopen("rightResult.txt","w");//清空 fclose(fp3); } void sort() //實現排序 {FILE *fp5; int i,j,m; s[0].avscore=A/nu; fp5=fopen("nrecord.txt","a+"); fprintf(fp5,"%s %s %f\n",s[0].name,s[0].num,s[0].avscore); //將剛剛做過的測試記錄到文件nrecord.txt中 fclose(fp5); fp5=fopen("nrecord.txt","rb"); for(i=0;!feof(fp5);i++) { fscanf(fp5,"%s %s %f\n",s[i].name,s[i].num,&s[i].avscore);} //將文件nrecord.txt的記錄存到結構體struct Student中 fclose(fp5); //實現排序 m=i; struct Student temp; for(i=0;i<m;i++) { for(j=0;j<m-1;j++) if(s[j].avscore<s[j+1].avscore) { strcpy(temp.name,s[j].name); //利用臨時結構變量temp實現數組元素的交換 strcpy(temp.num,s[j].num); temp.avscore=s[j].avscore; strcpy(s[j].name,s[j+1].name); strcpy(s[j].num,s[j+1].num); s[j].avscore=s[j+1].avscore; strcpy(s[j+1].name,temp.name); strcpy(s[j+1].num,temp.num); s[j+1].avscore=temp.avscore; } //若n=0,意味著沒有交換了,排序已經完成 } //輸出排名結果 printf(" ****************************************************************\n"); printf(" ---------查看你的排名(排序結果由高到低):--------------------\n"); printf(" -------------姓名 學號 分數------------\n"); for(i=0;i<m;i++) {printf(" %s %s %4.2f\n",s[i].name,s[i].num,s[i].avscore);}} void TestOver() //程序測試完畢函數 { printf("\n\n------測試完畢你的測試結果保存在 %s 中------\n\n",s[0].num); //輸出測試結果記錄提示 } void ShowResult() //顯示測試結果函數 { FILE *fp; if((fp=fopen("TestResult.txt","r"))==NULL) { printf("打開文件失敗\n"); exit(0);} char ch; ch=fgetc(fp); //文件開頭字符 while(ch!=EOF) //當文件沒有到尾時,一直循環 { putchar(ch); //輸出字符 ch=fgetc(fp);} fclose(fp); } void FileCopy() //文件復制函數,用來保存測試結果,當然文件名不能重復, { FILE *in,*out; strcat(s[0].num,".txt"); //將字符串".txt"連接到字符串student[0].num後,即以學號為文件名,後綴為.txt的文件中,保存在工程目錄下 if((in=fopen("TestResult.txt","r"))==NULL) { in=fopen("TestResult.txt","w+"); printf("無文件記錄,已新建.\n"); } if((out=fopen(s[0].num,"w"))==NULL) //打開文件學號.txt 文件(如03071361.txt),"w"方式為只寫方式 { printf("打開文件失敗\n"); exit(0); } while(!feof(in)) //當文件TestResult.txt沒有結束時循環 fputc(fgetc(in),out); //逐個字符寫入 fclose(in); fclose(out);} void ChooseFunc(); void begain() { printf("\n\n\n"); printf(" \n"); printf(" *************************************************************\n"); printf(" *--------------------------1.加法測試-----------------------*\n"); printf(" *--------------------------2.減法測試-----------------------*\n"); printf(" *--------------------------3.乘法測試-----------------------*\n"); printf(" *--------------------------4.除法測試-----------------------*\n"); printf(" *--------------------------5.返回主菜單----------------------*\n"); printf(" *------------------------------------------------------------*\n\n\n"); int choose,thnum; // bool judge=false; printf(" 選擇功能:"); scanf("%d",&choose); while(choose<1||choose>5) //不在以上所列的功能以內時循環 { printf(" 超出功能范圍,請重新選擇(1---5):"); scanf("%d",&choose); } switch(choose) //switch語句選擇執行功能 { case 1: //執行功能1 system("cls"); //清屏 printf("\n\n\n"); printf(" 加法測試:輸入要測試的題目數(5/10/20/50/100)::",&thnum); scanf("%d",&thnum); while(thnum<5||thnum>5&&thnum<10||thnum>10&&thnum<20||thnum>20&&thnum<50||thnum>50&&thnum<100||thnum>100) //不在以上所列的功能以內時循環 { printf("超出功能范圍,請重新選擇(5/10/20/50/100):"); scanf("%d",&thnum);} system("cls");//清屏 Addition(thnum); //調用加法運算函數 begain(); break; case 2: system("cls"); //清屏 printf("\n\n\n"); printf(" 減法測試:輸入要測試的題目數(5/10/20/50/100):",&thnum); scanf("%d",&thnum); while(thnum<5||thnum>5&&thnum<10||thnum>10&&thnum<20||thnum>20&&thnum<50||thnum>50&&thnum<100||thnum>100) //不在以上所列的功能以內時循環 { printf("超出功能范圍,請重新選擇(5/10/20/50/100):"); scanf("%d",&thnum);} system("cls"); //清屏 Subtracter(thnum); begain(); break; case 3: system("cls"); //清屏 printf("\n\n\n"); printf(" 乘法測試:輸入要測試的題目數(5/10/20/50/100):",&thnum); scanf("%d",&thnum); while(thnum<5||thnum>5&&thnum<10||thnum>10&&thnum<20||thnum>20&&thnum<50||thnum>50&&thnum<100||thnum>100)//不在以上所列的功能以內時循環 { printf("超出功能范圍,請重新選擇(5/10/20/50/100):"); scanf("%d",&thnum);} system("cls"); //清屏 printf("\n\n\n"); Multiplication(thnum); begain(); break; case 4: system("cls"); //清屏 printf("\n\n\n"); printf(" 除法測試:輸入要測試的題目數(5/10/20/50/100):",&thnum); scanf("%d",&thnum); while(thnum<5||thnum>5&&thnum<10||thnum>10&&thnum<20||thnum>20&&thnum<50||thnum>50&&thnum<100||thnum>100)//不在以上所列的功能以內時循環 { printf("超出功能范圍,請重新選擇(5/10/20/50/100):"); scanf("%d",&thnum);} system("cls"); //清屏 printf("\n\n\n"); Division(thnum);begain(); break; case 5: system("cls"); //清屏 ChooseFunc(); break;}} void ChooseFunc() //功能選擇函數 { printf("\n\n\n"); printf(" *************************************************************\n"); printf(" *--------------------------1.開始測試-----------------------*\n"); printf(" *--------------------------2.查看結果-----------------------*\n"); printf(" *--------------------------3.查看排名-----------------------*\n"); printf(" *--------------------------4.錯題重做-----------------------*\n"); printf(" *--------------------------5.結束測試 ----------------------*\n"); printf(" *-----------------------------------------------------------*\n\n\n"); int choose; printf(" 選擇功能:"); scanf("%d",&choose); while(choose<1||choose>5) //不在以上所列的功能以內時循環 { printf(" 超出功能范圍,請重新選擇(1---5):"); scanf("%d",&choose); } switch(choose) //switch語句選擇執行功能 { case 1: //功能1 system("cls"); printf(" *************************************************************\n"); { start =time(NULL); system("cls"); } //顯示時間 begain(); break; case 2: //功能2 system("cls"); printf("\n\n"); ShowResult(); //調用此函數,即輸出測試結果 ChooseFunc(); break; case 3: //功能2 system("cls"); printf("\n\n"); sort(); //調用此函數,即輸出測試結果 ChooseFunc(); break; case 4: //功能4 system("cls"); //清屏 printf("\n\n"); rework(); //調用此函數,即輸出測試結果 ChooseFunc(); break; case 5: //功能5 system("cls"); //清屏 printf("\n\n"); { end =time(NULL); printf(" *-----------------------------------------------------------------*\n"); printf(" *------------------小朋友你答題用時為:%d秒------------------------*\n",end-start); } FileCopy(); //調用此函數,即復制測試結果 TestOver(); break; } } int main(int argc, char *argv[]) { system("color b0"); FILE *fp,*fp2,*fp3; fp=fopen("TestResult.txt","w"); //以只寫方式打開文件,如果文件存在,則清空,這就是為什麼結束程序時要復制測試結果了 fp2=fopen("failedResult.txt","w"); //清空之前數據 fclose(fp2); fp3=fopen("rightResult.txt","w"); //清空 fclose(fp3); Judge(); //調用此函數 Savemessage(); //調用此函數 ChooseFunc(); //調用此函數 }