飞道的博客

C语言实现自动出题、单词拼写等功能,附带管理员模式

307人阅读  评论(0)

前言

用最基础的C语言做了一个调试窗口,实现了自动数学计算出题,单词拼写的功能,并且设有管理员模式,可以设置题目的难度,并且不同的题目难度可以赋予不同的分数。

视图浏览:

注意:C语言大作业,该项目仅供参考,严禁抄袭!

需求分析

	需求:
	1.自动出题,可以实现加减乘除
	(1)自动出题
	(2)实现加减乘除
	(3)出题量固定为10 
	(4)输出最终的成绩 
	2.用调试窗口做一个简单的UI界面
	(1)登陆功能 
	(2)<1>做数学题<2>单词拼写<3>成绩查询 
	3.管理员模式,可以设定题目难度 


根据这样的需求,可以制作一个简单的调试窗口。

说一下一些细节的分析:
(1)关于自动出题
可以使用随机数的方式自动产生随机数,方法如下:

/*
 * 输入n,表示会生成一个(0,n]的随机数 
 */
#include<stdlib.h>
#include<stdio.h>
int getRandom(int n)
{
   
	int ans;
	ans = rand() % n;
	while(ans==0)
	{
   
		ans = rand() % n;//防止求余数后ans为0 
	}
	return ans;
}

但事实上,使用rand()函数有很大的弊端,因为rand()的伪随机数太伪了,每一次生成的数字顺序都是一样的,不信?你把我下面的代码copy自己去运行一遍,每次出来的结果都是一样的…

#include<stdlib.h>
#include<stdio.h>
int main()
{
   
	int mid;
	for(int i=0;i<10;i++)
	{
   
		mid = rand()%100;
		printf("%d\n",mid);
	}
	return 0;
}


所以这种随机数太不可靠了,我们需要自己创建一个随机数。那么怎样可以每次都生成不一样的随机数呢?我想大家都想到了,用时间戳的方法,当前时间的ms数是很难确定的;还有一个就是程序运行的时间,以ms数计算,也很难确定,根据这个思路,我们有了下面两个随机因子。

int random[1000];//这里我设计了一个随机数数组,一次性将随机数存到里面,但事实上着并不是最终输出的随机数
void encryption()
{
   
	SYSTEMTIME st={
   0};
	GetLocalTime(&st); 
	long nowTime = st.wMilliseconds;//获取随机因子1(ms) ,即系统当前时间ms数
	long nowSecondTime = st.wSecond;//获取随机因子2(s) ,即系统当前时间s
	long mid = nowTime * nowSecondTime; //获取随机因子3 
	if(mid ==0)//防止程序错误
	{
   
		printf("程序错误,请重启\n");
		return;
	}
	
	random[0] = mid ;
	//随机数组初始化(当前数组范围为(1,1000)(可修改,暂未实现)) 
	long long int realRandom;//获取随机因子4 
	for(int i=1;i<1000;i++)
	{
   
		//创建一个随机数
	    realRandom = i+nowTime*i*mid % Llimit;
	    //realRandom = rand() * (i*i);
		int j=3;
	    while(realRandom <=0)
	    {
   
			realRandom=j+nowTime*(j*i)%Llimit;
			j+=j%1000;
		}
		random[i] = realRandom;
	}
	//随机数因子调试 
//		for(int i =0;i<1000;i++)
//		{
   
//			printf("%d\n",random[i]);
//		} 
} 

(2)关于设计方式
对于每一种功能,可以单独使用一个或多个函数来实现,以模块化的原则来设计程序,可以更好地提高程序的健壮性和鲁棒性,方便后续的代码修改和扩展。因为C是面向过程的语言,所以在设计模块化项目的类型上不占优势,但是对于这种小量级的应用还是不成问题的。详细的设计思路可以参考下述主代码。

主程序代码:

#include<stdio.h>
#include<time.h>
#include<unistd.h>
#include<windows.h>
#include<stdlib.h>
/*
	需求:
	1.自动出题,可以实现加减乘除
	(1)自动出题
	(2)实现加减乘除
	(3)出题量固定为10 
	(4)输出最终的成绩 
	2.用调试窗口做一个简单的UI界面
	(1)登陆功能 
	(2)<1>做数学题<2>单词拼写<3>成绩查询 
	3.管理员模式,可以设定题目难度 
*/
/*变量声明*/ 
int score;//成绩 
clock_t start, finish;//时钟 
double duration;//持续时间 
long long int random[1000];//随机数组[当前范围为1-1000,可设定]
int index;//随机数下标 
bool isFirst=true;//判断是否为第一次进入登陆界面,修改界面细节 
int Llimit=10;//设置数学题的出题范围 
int hard=1;//数学题难度 

/*函数初始化声明*/
void login();
void doMath();
void encryption();
void doWordSplling();
void clockStart();
void clockFinish();
void adminLogin();
void enterAdmin();
void printLine();
int setLimit(int n);
int getRandom(int n);
void modifyRank(int n);
void printScore(int localScore);
void judgeIndex(int index);
void isRepeat(int *a,int *b,int *sign);

/*
 * 主函数入口 
 */
int main()
{
   
	login();
}

/*
 * 登陆界面 
 */
void login()
{
   
	clockStart();
	printLine();
	if(isFirst)printf("* 欢迎使用全球最先进的答题系统   *\n");
	printf("* 1.做数学题                     *\n"); 
	printf("* 2.做单词拼写题                 *\n");
	printf("* 3.成绩查询                     *\n");
	printf("* 4.管理员模式                   *\n");
	printf("* 5.退出                         *\n");
	printLine();
	printf("\n");
	printf("请输入你一个数字(功能如上):");
	int n;
	scanf("%d",&n);
	while(n>5||n<1)
	{
   
		printf("错误的输入,请重新输入:");
		scanf("%d",&n);
	} 
	clockFinish();//随机数初始化完成 
	switch(n)
	{
   
		case 1:
			doMath();
			break;
		case 2:
			doWordSplling();	
			break;
		case 3:
			printLine();
			printf("当前成绩为:%d		 	 *\n",score); 
			printLine();
			break;
		case 4: 
			adminLogin();
			break;
		case 5:
			printf("exit\n");
			return;	
	}
} 

/*
 * 单词拼写 
 */
void doWordSplling()
{
   
	int localScore;
	int i =33;
	while(i-->0)printf("*");
	printf("\n"); 
	printf("正在出题,请稍后.....\n");
	sleep(1);
	int ans;
	char word[100];
	for(int j=0;j<3;j++)
	{
   
		ans=getRandom(3);
		switch(ans)
		{
   
			case 1:
				printf("请输入苹果的英文:");
				scanf("%s",word);
				if(strcmp(word,"apple")==0)
				{
   
					printf("你真棒~\n");
					localScore++;
				}
				else
				{
   
					printf("拼错了哦~\n");
				}
				break;
			case 2:
				printf("请输入香蕉的英文:");
				scanf("%s",word);
				if(strcmp(word,"banana")==0)
				{
   
					printf("你真棒~\n");
					localScore++;
				}
				else
				{
   
					printf("拼错了哦~\n");
				}
				break;
			case 3:
				printf("请输入昨天的英文:");
				scanf("%s",word);
				if(strcmp(word,"yesterday")==0)
				{
   
					printf("你真棒~\n");
					localScore++;
				}
				else
				{
   
					printf("拼错了哦~\n");
				}
				break;
		}
	}
	printScore(localScore);
	
}

/*
 * 出数学题,通过运行时间戳来计算随机数
 * 题目包括加减乘除四则运算
 */
void doMath()
{
   
	int a1,b1,c,ans,localScore;
	//加载界面 
	printf("正在出题,请稍后.....\n");
	sleep(1);
	printLine();
	int kind;
	//题目初始化,十道题目一次性放进三个数组中
	//如果存在重复的题目则重新出题 (暂时取消该功能)
	for(int i=0;i<10;i++)
	{
   
		//加减乘除选择一个
		//注意:为了程序的稳定性,暂时未实现除法 
		kind = getRandom(3);//1为加法,2为减法,3为除法,4为乘法 
		a1=getRandom(Llimit);
		b1=getRandom(Llimit);
		switch(kind)
		{
   
			case 1://加法
				c = a1+b1;
				printf("%d.%d+%d=",(i+1),a1,b1);
				scanf("%d",&ans);
				if(c==ans)localScore +=hard;
				break;
			case 2://减法 
				c = a1-b1;
				printf("%d.%d-%d=",(i+1),a1,b1);
				scanf("%d",&ans);
				if(c==ans)localScore +=hard;
				break;
			case 3://乘法 
				c = a1*b1;
				printf("%d.%d*%d=",(i+1),a1,b1);
				scanf("%d",&ans);
				if(c==ans)localScore +=hard;
				break;
		}
	} 
	printScore(localScore);
	return;
}


/*
 * 打印横线 
 */
void printLine()
{
   
	int i=34;
	while(i-->0) printf("*");
	printf("\n");
}

/*
 * 管理员模式 
 */
void adminLogin()
{
   
	printf("please input your password:");
	char str[6];
	scanf("%s",str);
	int count=0; 
	while(count <=5)
	{
   
		count ++;
		if(strcmp(str,"123456")==0)
		{
   
			enterAdmin();
			break;
		}
		printf("Your password is wrong,please check it agagin!\n");
		scanf("%s",str);
	}
	printf("Goodbye~\n");
}
/*
 * 进入管理员模式 
 */
void enterAdmin()
{
   
	printLine();
	int ans;
	printf("Welcome to admin mode.   	 *\n"); 
	printf("1.简单模式			 *\n");//默认难度 
	printf("2.普通模式			 *\n");
	printf("3.炼狱模式			 *\n");  
	printLine();
	printf("请输入功能码:");
	scanf("%d",&ans);
	modifyRank(ans);
}
/*
 * 修改模式 
 */
void modifyRank(int ans)
{
   
	switch(ans)
	{
   
		case 1:
			Llimit = setLimit(10);
			hard =1;
			break;
		case 2:
			Llimit = setLimit(1000);
			hard =2;
			break;
		case 3:
			Llimit = setLimit(100000);	
			hard =3;
			break;
	}
	printf("当前limit为%d",Llimit); 
	printf("修改成功\n");
	isFirst = false;
	login();
	
}

/*
 * 打印成绩 
 */
void printScore(int localScore)
{
   
	score +=localScore;
	printLine();
	printf("当前成绩为%d			 *\n",score);
	printf("本局成绩为%d			 *\n",localScore);
	printLine();
	isFirst = false;
	login();
}

/*
 * 该算法执行后会完成随机数数组初始化 
 * 注意:该随机算法只有结束了一个时间周期之后才可以执行 
 */
void encryption()
{
   
	SYSTEMTIME st={
   0};
	GetLocalTime(&st); 
	long nowTime = st.wMilliseconds;//获取随机因子1(ms) 
	long nowSecondTime = st.wSecond;//获取随机因子2(s) 
	long mid = nowTime * nowSecondTime; //获取随机因子3 
	if(mid ==0)
	{
   
		printf("程序错误,请重启\n");
		return;
	}
	random[0] = mid ;
	//int sort = rand();
	//printf("mid=%d",mid);
	//随机数组初始化(当前数组范围为(1,1000)(可修改,暂未实现)) 
	long long int realRandom;//获取随机因子4 
	for(int i=1;i<1000;i++)
	{
   
		//创建一个随机数
	    realRandom = i+nowTime*i*mid % Llimit;
	    //realRandom = rand() * (i*i);
		int j=3;
	    while(realRandom <=0)
	    {
   
			realRandom=j+nowTime*(j*i)%Llimit;
			j+=j%1000;
		}
//		printf("%d\n",realRandom);
		random[i] = realRandom;
	}
	//随机数因子调试 
//		for(int i =0;i<1000;i++)
//		{
   
//			printf("%d\n",random[i]);
//		} 
} 

/*
 * 设置随机数组的范围,默认值为1000
 * 随机值的难度随着选择的难度而调整 
 */
int setLimit(int n)
{
   
	return n;
} 

/*
 * 从随机数组中获取随机数 
 * 输入一个数字,返回 (0,n]的范围 
 */
int getRandom(int n)
{
   
	int ans = random[index]%(n+1);
	while(ans ==0)//ans不能为0 
	{
   
		index++;
		judgeIndex(index);
		ans = random[index] % (n+1);
	}	 
	index++;
	judgeIndex(index);
	//printf("ans=%d\n",ans);
	return ans;
}

/*
 * 判断数组是否越界 
 */
void judgeIndex(int index)
{
   
	if(index>999)
	{
   
		index =1;
	}
}

/*
 * 程序启动时启动该时钟 
 */
void clockStart()
{
   
	start = clock();
}

/*
 * 时钟结束函数
 * 此函数只有在出题前才会调用 
 */ 
void clockFinish()
{
   
	finish = clock();
	duration = (double)(finish - start)*1000000 / CLOCKS_PER_SEC;;
	//printf("%lf",duration);
	encryption();//启用高级加密算法提供随机数 
}

注意事项:
(1)C语言大作业,该项目仅供参考,严禁抄袭!
(2)dev写的程序,用vc大概率跑不了,vc版本太老了,编译器有很多不一样的地方。

参考文献:
(1)https://jrhar.blog.csdn.net/article/details/80499906
(2)https://blog.csdn.net/sea_snow/article/details/82752492


转载:https://blog.csdn.net/linZinan_/article/details/115712808
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场