课程报告课程名称:程序设计实践专业班级:计算机类1304班****:**学号: ****************:***学期:2013-2014学年第二学期课程报告任务书成绩评定教师:1 需求分析该系统包括以下功能:1.进行随机答题并判卷2.显示试题所有内容3.插入试题4.添加试题5.自主选题并判卷6.修改试题7.删除试题8.退出系统2 概要设计2.1整体框架图图2-1-12.2 函数功能图2.2.1 随机答题并判卷功能图图2-2-12.2.2 修改试题功能图N图2-2-22.2.3 删除试题功能图图2-2-3 2.3 自定义函数3 详细设计3.1 添加试题将想要输入的是试题,从键盘输入,题库中总的题数作为结构数组的下标,存入一道题就将结构数组的下标向后移动一位,最后将存入最后一道题的下标返回,作为题库中的总题数。
Status AddNode(int &N) //添加试题内容{printf("如果不添加了试题了,在题目输入“*”结束!\n");while(1){printf("请输入所要插入题题目、题干和选项:\n");printf("请输入题目:");gets(Testquestions[N].subject);if(strcmp(Testquestions[N].subject,"*")==0)break;printf("请输入选项A:");gets(Testquestions[N].option1);printf("请输入选项B:");gets(Testquestions[N].option2);printf("请输入选项C:");gets(Testquestions[N].option3);printf("请输入选项D:");gets(Testquestions[N].option4);printf("请输入答案:");scanf("%c",&Testquestions[N].result);getchar();N++; //N表示结构体数组长度,通过加&号使其值能返回}return TRUE;}3.2 修改试题先从键盘中输入想要修改第几道试题,当题标输入m时,找到结构数组m-1对应的元素就是要修改的试题,再将修改的试题进行保存,从而实现对试题的修改功能。
Status Change(int &N){int m,i;printf("请输入您要修改第几题?\n");scanf("%d",&m);getchar(); //吸收空格字符for(i=0;i<N;i++){if(i==(m-1)){printf("请输入新的题目:");gets(Testquestions[m-1].subject);printf("请输入新的选项A:");gets(Testquestions[m-1].option1);printf("请输入新的选项B:");gets(Testquestions[m-1].option2);printf("请输入新的选项C:");gets(Testquestions[m-1].option3);printf("请输入新的选项D:");gets(Testquestions[m-1].option4);printf("请输入新的答案:");scanf("%c",&Testquestions[m-1].result);getchar();break;}}if(m>N)printf("修改试题失败!\n");elseprintf("修改试题成功!\n");return TRUE;}3.3 删除试题先从键盘中输入想要修改第几道试题,当题标输入n时,找到结构数组n-1对应的元素就是要删除的试题,在用一个for循环,将n到N-1个元素向前移动,从而实现对试题的删除功能。
Status DeleteNode(int &N) //删除数组中的第n道题{int n;printf("输入你想是删除第几道试题:\n");scanf("%d",&n);if(n>N){printf("删除不成功\n");return ERROR;}while(n<=N){Testquestions[n-1]=Testquestions[n];n++;}N=N-1;printf("删除成功\n");return TRUE;}3.4 随机选题并判题学生进入考试系统,输入形成试卷的题数,系统将会自动抽取试题,在进行作答之后,立刻能看到学生是否做对本道试题,如果作对,将会显示“答案正确”,否者会显示“答案错误”并且会显示正确答案。
void answer(int sum,int N) //随机进行答题{int i,score=0,Num;char r;for(i=1;i<=sum;i++){Num= rand()%N; //随机函数,以随机选定何题进行解答 printNode(Testquestions[Num],i);printf("\n");printf("\n请输入第(%d)答案:",i);scanf("%c",&r);getchar();if(Match(Testquestions[Num],r)) //调用函数Match判断所输入的答案与标准答案是否相同{ printf("\n答案正确!\n");score++;}else {printf("\n答案错误!\n");printf("正确答案为:%c\n",Testquestions[Num].result);}}printf("\n你的总成绩为:%d\n",score);}3.5 自主选题并判题通过函数中传递题库的总数和要形成试卷的总题数,输入将要选择的试题,将输入的试题在结构数组中找到,可以进行作答,当输入的答案不与标准答案匹配时,答卷系统将会自动报错,并且输出正确的答案,如果输入正确将会显示“答案正确”,在最后答卷系统将会输出总的成绩。
void Otheranswer(int N,int s){int i,score=0,k;char m;for(i=1;i<=s;i++){printf("输入要选择第几题?\n");scanf("%d",&k);while(k<=0||k>N){printf("输入的题号在题库中不存在!\n");printf("\n请重新输入正确的题号:");scanf("%d",&k);}printNode(Testquestions[k-1],i);printf("\n请输入(%d)答案:",i);getchar();scanf("%c",&m);getchar();if(m==Testquestions[k-1].result){printf("答案正确!\n");score++;}else{printf("正确答案为:%c\n",Testquestions[k-1].result);}}printf("总分为:%d\n",score);}3.6登陆考试系统函数屏幕上会显示教师和学生两种端口,如果过选择学生端口将会进入登陆和注册两个选项,已经注册过的就可以直接登陆了,反之则进行注册。
进入学生答题系统后可以选择随机答题或者自主选题进行作答两种方式。
登陆教师窗口后,可以直接查看试题、删除试题、修改试题、添加试题的功能。
void Denglu(){FILE *fp1;int a,c,num,flag=1;int i=0;char Mima[20]="\0",b[20];printf("\t\t\t1 进入登录\n");printf("\n\t\t\t2 进入注册\n");scanf("%d",&c);while(flag){if(c<1||c>2){printf("\n请输入正确的选项!\n");scanf("%d",&c);flag=1;}elseflag=0;}if(c==2){Zhuce();}else{if((fp1=fopen("student.txt","rb"))==NULL){printf("打开文件失败!");exit(0);}printf("请输入学号:");scanf("%d",&num);printf("请输入密码");while((c=getch())!='\r'){Mima[i]=c;i++;if(c!='\b')printf("*");elseprintf("\b\b");}rewind(fp1);while(!feof(fp1)){fscanf(fp1,"%d",&a);fscanf(fp1,"%s",&b);if(a==num&&strcmp(b,Mima)==0)break;while(a!=num||strcmp(b,Mima)!=0){i=0;printf("\n错误,重新输入:\n");printf("请输入学号:");scanf("%d",&num);printf("请输入密码");while((c=getch())!='\r'){Mima[i]=c;i++;if(c!='\b')printf("*");elseprintf("\b\b");}rewind(fp1);while(!feof(fp1)){fscanf(fp1,"%d",&a);fscanf(fp1,"%s",&b);if(a==num&&strcmp(b,Mima)==0)break;}}printf("\t\t欢迎登陆单选题标准化考试系统!\n");system("pause");getchar();if(fclose(fp1)){printf("关闭文件失败!\n");exit(0);}}}*源代码#include <stdio.h>#include <stdlib.h>#include<string.h>#include<conio.h>#define TRUE 1#define ERROR 0#define MAX 30typedef int Status;typedef struct{char option1[30],option2[30],option3[30],option4[30],subject[150];char result;int q;}TestNode;TestNode Testquestions[MAX];Status SaveNode(int &N) //把结构体数组保存到文件"cheng"中,如成功保存返回TRUE,否则返回ERROR{ int i;FILE *fp;return ERROR;for(i=0;i<N;i++)fwrite(&Testquestions[i],sizeof(TestNode),1,fp);fclose(fp);return TRUE;}Status ReadNode(int &N) //从文件读出结构体数组的内容,如成功读取返回TRUE,否则返回ERROR{ FILE *fp;int i=0;if((fp=fopen("cheng","rb"))==NULL)return ERROR;while(!feof(fp)) // 用feof检测文件是否结束,如果结束,返回正确{ fread(&Testquestions[i],sizeof(TestNode),1,fp);i++;}N=i-1;return TRUE;}void Zhuce(){void Denglu();int i,m;i=0;char n[20]="\0",c;if((fp1=fopen("student.txt","ab"))==NULL) {printf("打开文件失败!\n");exit(0);}printf("请注册学号:");scanf("%d",&m);fprintf(fp1,"%d ",m);printf("请设置密码(20字符以内):");while((c=getch())!='\r'){n[i]=c;i++;if(c!='\b')printf("*");elseprintf("\b\b");}fprintf(fp1,"%s\n",n);if(fclose(fp1)){printf("关闭文件失败!\n");exit(0);printf("\n");printf("\t\t\t注册完成!\n");Denglu();}void Denglu(){FILE *fp1;int a,c,num,flag=1;int i=0;char Mima[20]="\0",b[20];printf("\t\t\t1 进入登录\n");printf("\n\t\t\t2 进入注册\n");scanf("%d",&c);while(flag){if(c<1||c>2){printf("\n请输入正确的选项!\n");scanf("%d",&c);flag=1;}elseflag=0;}if(c==2){printf("请注册:\n");Zhuce();}elseif((fp1=fopen("student.txt","rb"))==NULL){printf("打开文件失败!");exit(0);}printf("请输入学号:");scanf("%d",&num);printf("请输入密码");while((c=getch())!='\r'){Mima[i]=c;i++;if(c!='\b')printf("*");elseprintf("\b\b");}rewind(fp1);while(!feof(fp1)){fscanf(fp1,"%d",&a);fscanf(fp1,"%s",&b);if(a==num&&strcmp(b,Mima)==0)break;}while(a!=num||strcmp(b,Mima)!=0)i=0;printf("\n错误,重新输入:\n");printf("请输入学号:");scanf("%d",&num);printf("请输入密码");while((c=getch())!='\r'){Mima[i]=c;i++;if(c!='\b')printf("*");elseprintf("\b\b");}rewind(fp1);while(!feof(fp1)){fscanf(fp1,"%d",&a);fscanf(fp1,"%s",&b);if(a==num&&strcmp(b,Mima)==0)break;}}printf("\t\t欢迎登陆单选题标准化考试系统!\n"); system("pause");getchar();printf("\n");if(fclose(fp1))printf("关闭文件失败!\n");exit(0);}}}Status AddNode(int &N) //添加试题内容{printf("如果不添加了试题了,在题目输入“*”结束!\n");while(1){printf("请输入所要插入题题目、题干和选项:\n");printf("请输入题目:");gets(Testquestions[N].subject);if(strcmp(Testquestions[N].subject,"*")==0)break;printf("请输入选项A:");gets(Testquestions[N].option1);printf("请输入选项B:");gets(Testquestions[N].option2);printf("请输入选项C:");gets(Testquestions[N].option3);printf("请输入选项D:");gets(Testquestions[N].option4);printf("请输入答案:");scanf("%c",&Testquestions[N].result);printf("请输入试题难度:");scanf("%d",&Testquestions[N].q);getchar();N++; //N表示结构体数组长度,通过加&号使其值能返回}return TRUE;}void printNode(TestNode p,int n) //输出第n道题题目{printf("(%d) ",n);printf("%s\n",p.subject);printf(" A %s ",p.option1);printf(" B %s \n",p.option2);printf(" C %s ",p.option3);printf(" D %s ",p.option4);printf(" 试题难度为:%d\n",p.q);}Status Change(int &m){int i;printNode(Testquestions[m-1],m);printf("\n");printf("修改题目请按 1\n");printf("修改选项A请按 2\n");printf("修改选项B请按 3\n");printf("修改选项C请按 4\n");printf("修改选项D请按 5\n");printf("修改标准答案请按 6\n");printf("修改试题难度请按 7\n");scanf("%d",&i);getchar(); //吸收空格字符switch(i){case 1: printf("\n请输入新的题目:");gets(Testquestions[m-1].subject);break;case 2:printf("请输入新的选项A:");gets(Testquestions[m-1].option1);break;case 3: printf("请输入新的选项B:");gets(Testquestions[m-1].option2);break;case 4:printf("请输入新的选项C:");gets(Testquestions[m-1].option3);break;case 5:printf("请输入新的选项D:");gets(Testquestions[m-1].option4);break;case 6:printf("请输入新的答案:");scanf("%c",&Testquestions[m-1].result);break;case 7:printf("请输入新的试题难度:");scanf("%d",&Testquestions[m-1].q);break;default:printf("请输入正确的修改选项\n");break; }return TRUE;}Status InsertNode(int &N){int i,j,P;printf("输入要插入到第几题?\n");scanf("%d",&i);getchar();N=N+1;for(j=N-1;j>=(i-1);j--){Testquestions[j]=Testquestions[j-1];}printf("请输入题目:");gets(Testquestions[i-1].subject);printf("请输入选项A:");gets(Testquestions[i-1].option1);printf("请输入选项B:");gets(Testquestions[i-1].option2);printf("请输入选项C:");gets(Testquestions[i-1].option3);printf("请输入选项D:");gets(Testquestions[i-1].option4);printf("请输入答案:");scanf("%c",&Testquestions[i-1].result);printf("请输入试题难度:");scanf("%d",&Testquestions[i-1].q);getchar();return TRUE;}Status DeleteNode(int &N) //删除数组中的第n道题{int n;printf("输入你想是删除第几道试题:\n");scanf("%d",&n);if(n>N){printf("删除不成功\n");return ERROR;}while(n<=N){Testquestions[n-1]=Testquestions[n];n++;}N=N-1;printf("删除成功\n");return TRUE;}Status Match(TestNode p,char m) //判断m是否为p题目的答案,若是返回TRUE,否则返回ERROR{if(m==p.result)return TRUE;elsereturn ERROR;}void answer(int sum,int N) //随机进行答题{int i,score=0,Num;char r;for(i=1;i<=sum;i++){Num= rand()%N; //随机函数,以随机选定何题进行解答 printNode(Testquestions[Num],i);printf("\n");printf("\n请输入第(%d)答案:",i);scanf("%c",&r);getchar();if(Match(Testquestions[Num],r)) //调用函数Match判断所输入的答案与标准答案是否相同{ printf("\n答案正确!\n");score++;}else {printf("\n答案错误!\n");printf("正确答案为:%c\n",Testquestions[Num].result);}}printf("\n你的总成绩为:%d\n",score);}void Otheranswer(int N,int s){int i,score=0,k,j,y;char m;for(i=1;i<=s;i++){printf("输入试题难度\n");scanf("%d",&k);while(k<0||k>2){printf("题库中没有该难度的试题!\n");printf("\n请重新输入试题难度:");scanf("%d",&k);}for(j=0;j<N;j++){if(y==j)continue;if(Testquestions[j].q==k){printNode(Testquestions[j],i);printf("\n请输入(%d)答案:",i);getchar();scanf("%c",&m);getchar();if(Match(Testquestions[j],m)){printf("答案正确!\n");score++;}else{printf("答案错误!\n");printf("正确答案为:%c\n",Testquestions[j].result);}break;}y=j;}}printf("总分为:%d\n",score);}void main(){char flag;int N=0,i,sum,m,s,score=0,chose,Chose=3;ReadNode(N);while(Chose<1||Chose>2){printf("\t\t\t请选择自己的类型\n");printf("\t\t\t1 学生端口\n");printf("\t\t\t2 教师端口\n");scanf("%d",&Chose);}system("cls");switch(Chose){case 1:Denglu();system("cls");while(1){printf("\t\t\t单项选择题标准化考试系统进行答题\n ");printf("\t\t\t1 进行随机答题并判卷\n");printf("\t\t\t2 自主选题并判卷\n");printf("\t\t\t3 退出系统\n");scanf("%d",&chose);getchar();switch(chose){case 1:system("cls");ReadNode(N);printf("请输入试题的总题数:");scanf("%d",&sum);getchar();if(N==0){printf("对不起,题库中没有试题!\n");printf("按任意键回到菜单!\n");getchar();}elseanswer(sum,N);getchar();break;case 2:system("cls");ReadNode(N);printf("请输入试卷的总题数:");scanf("%d",&s);Otheranswer(N,s);getchar();break;case 3:printf("你将退出系统(Y or N)?");scanf("%c",&flag);getchar();if(flag=='Y'||flag=='y') exit(0);system("cls");break;default:printf("请输入正确选择!\n");}}case 2:printf("\t\t\t欢迎进入教师题库管理\n");while(1){printf("\t\t\t单项选择题标准化考试系统\n "); printf("\n");printf(" \t\t\t1 显示所有试题内容\n");printf(" \t\t\t2 添加试题\n");printf(" \t\t\t3 修改试题\n");printf(" \t\t\t4 删除试题\n");printf(" \t\t\t5 插入试题\n");printf(" \t\t\t6 退出系统\n");scanf("%d",&chose);getchar();switch(chose){case 1:system("cls");ReadNode(N);if(N==0){printf("题库中没有试题!\n");printf("按任意键回到菜单!\n");getchar();}for(i=1;i<=N;i++){ printNode(Testquestions[i-1],i);printf("\n");}break;case 2:system("cls");ReadNode(N);AddNode(N);if(SaveNode(N))printf("试题添加成功!\n");elseprintf("试题添加失败!\n");break;case 3:system("cls");printf("请输入您要修改第几题?\n");scanf("%d",&m);ReadNode(m);Change(m);if( SaveNode(m))printf("修改成功\n");elseprintf("修改失败");break;case 4:system("cls");ReadNode(N);DeleteNode(N);SaveNode(N);break;case 5:system("cls");ReadNode(N);InsertNode(N);if(SaveNode(N))printf("插入试题成功\n");elseprintf("插入试题失败\n");break;case 6:printf("你将退出系统(Y or N)?");scanf("%c",&flag);getchar();if(flag=='Y'||flag=='y') exit(0);system("cls");break;default:printf("请输入正确选择!\n");}}}}4 调试分析在添加函数InsertNode中,在添加试题的过程中,不知道怎么在一个循环中不断添加试题,最后通过在c语言书中,看到用一个‘*’作为结束标志来结束试题的添加,用一个while 循环实现了添加功能。