基于c语言的小学生心算CAI系统
基本的功能描述
本系统可以用来进行单独的的加、减、乘、除心算练习,也可综合心算的速度与正确率进行测试。当用户在进行简单的四则运算时运算速度和正确率都较高时,可以进入四则混合运算,借此来进一步提高自己的心算能力。
系统需求分析
本小学生心算CAI系统为的是锻炼小学生的心算能力,所以需要出的大部分为简单的单独加减乘除的计算和综合的加减乘除的有关训练,所以可以将这些功能全部封装成独立的函数,在这些函数里面用了一些if的判断和算法的处理来排除计算中的不能整除的题目和会产生负数的题目,该系统还包含一些用户界面菜单和登陆界面的显示,这些可以用递归调用来实现这些菜单的显示和运算的循环,以及登陆的数据储存在计算机,方便读取和储存,以及心算的使用记录储存在文本格式的文件中,方便储存和读取。
下图为系统功能模块图
系统功能主要分为两大部分:
1.用户的登陆和注册。
2.CAI主系统的实现(随机运算和阶段性提升运算):`
1)加法运算。
2)减法运算。
3)乘法运算。
4)除法运算。
5)提升阶段性运算。
详细设计
下面是所用的函数的功能和定义的全局变量来实现的函数功能
#define COUNT 10//进阶运算要达到的运算量
#define COUNT_TRUE 5 //进阶运算必须要计算正确数
typedef struct
{
char name[50];//用户名
char data[200];//用户密码
}user;//创建一个user的结构体变量,来储存临时的用户的密码和账户和文件的用户密码和账户,
void menu1();//显示菜单1进入加减法的菜单。
void menu2();//进入菜单2的登陆界面 。
int count;//做题总数的全局变量方便统计做题总数。
int count_true;//做对的题目的全局变量方便统计做题总数。
int count_false;//做错的题目的全局变量方便统计做题总数
void add();//加法计算,随机显示两个数的加法,并统计做题数,错题数和对题数
void sub();//减法计算,随机显示两个数的减法,统计做题数,错题数和对题数
void muti();//乘法计算,随机显示两个数的乘法并统计做题数,错题数和对题数
void div();//除法计算,随机显示两个数的除法,统计做题数,错题数和对题数
void mix();//混合计算,随机显示三个数的混合运算,并统计做题数,错题数和对题数
void exit_menu1();//退出回到menu1
void exit_menu2();/退出回到menu2
void enter_advance();//进入进阶模式的判断,每到运算量达到COUNT和正确数达到COUNT_TRUE则让你选择是否进入进阶模式
int is_regsite(user *buf);//判断是否被注册,如果被注册则退回主菜单
void do_register(user *buf);//注册用户,将用户信息和密码保存在user.c文件中
void do_login(user *buf);//用户登陆,将输入的用户信息和密码和user.c的文件的信息匹配,如果正确匹配则进入menu2。
void save_add(int a, int b, int c);//储存加法在count.txt里面
void save_sub(int a, int b, int c);//储存减法 在count.txt里面
void save_muti(int a, int b, int c);//储存乘法 在count.txt里面
void save_div(int a, int b, int c);//储存除法在count.txt里面
void save_mix0(int a, int b, int c);//储存混合运算0 在count.txt里面
void save_mix1(int a, int b, int c);//储存混合运算 1 在count.txt里面
void save_mix2(int a, int b, int c);//储存混合运算 2 在count.txt里面
void save_mix3(int a, int b, int c);//储存混合运算 3 在count.txt里面
类层次图如下
程序运行结果效果图
设计总结
在小学生计算过程完美的避开了负数和不能整除的问题,人机交互功能良好,可以多次进行运算和返回主菜单。还可以查看自己做过的心算的题目,在本地文件下查看。
不足之处:在加了Esc随时退出的功能的情况下,每次输入运算的正确答案需要按两次才能出现,在getch()函数中直接读取了才能输入所以才出现这个问题。
代码如下
#include<stdio.h>
#include <stdlib.h>
#include <windows.h>
#include<conio.h>
#include<time.h>
#define COUNT 3//进阶运算要达到的运算量
#define COUNT_TRUE 1 //进阶运算必须要计算正确数
typedef struct
{
char name[50];//用户名
char data[200];//用户密码
}user;//创建一个user的结构体变量
void menu1();//
void menu2();
int count;//做题总数
int count_true;//做对的题目的量
int count_false;//做错的题目数量
void add();//加法计算
void sub();//减法计算
void muti();//乘法计算
void div();//除法计算
void mix();//混合计算
void exit_menu1();//退回menu1
void exit_menu2();//退回menu2
void enter_advance();//进入进阶模式的判断
int is_regsite(user *buf);//判断是否被注册
void do_register(user *buf);//注册用户
void do_login(user *buf);//用户登陆
void save_add(int a, int b, int c);//储存加法在count.txt里面
void save_sub(int a, int b, int c);//储存减法 在count.txt里面
void save_muti(int a, int b, int c);//储存乘法 在count.txt里面
void save_div(int a, int b, int c);//储存除法在count.txt里面
void save_mix0(int a, int b, int c);//储存混合运算0 在count.txt里面
void save_mix1(int a, int b, int c);//储存混合运算 1 在count.txt里面
void save_mix2(int a, int b, int c);//储存混合运算 2 在count.txt里面
void save_mix3(int a, int b, int c);//储存混合运算 3 在count.txt里面
int main()
{
menu2();
}
//判断是否被注册
int is_regsite(user *buf)
{
char name[30];//用来保存从user_info.txt读取的用户名和密码
FILE *fp=fopen("user.txt","r");
while(fgets(name,sizeof(name),fp) != NULL)
{
if (strncmp(name,buf->name,strlen(buf->data))==0)//判断name和 文件里面的name比较
{
return 1;//如果相等说明有用户注册,返回1
}
}
return 0; //如果没有注册返回0
}
void do_regsite(user *buf)
{
FILE *fp=fopen("user.txt","a+");
printf("请您输入要注册的用户名:\n");
loop:
scanf("%s",buf->name);
if (is_regsite(buf))//代表已经被注册了
{
printf("不好意思这个账户已经被注册了\n");
Sleep(100);
system("cls");//清屏函数
menu2();//退出到上一个界面menu2
}
printf("请您输入要注册的用户密码:\n");
scanf("%s",buf->data);
fprintf(fp,"%s %s\n",buf->name,buf->data);
printf("恭喜你注册成功");
fclose(fp);
}
void do_login(user *buf)
{
printf("请您输入要登录的用户名:\n");
scanf("%s",buf->name);
printf("请您输入要登录的用户密码:\n");
scanf("%s",buf->data);
char name_passwd[100] = { 0 };//用来保存从user_info.txt中读取出一行用户名和密码
char user_info[100] = { 0 };//用来输入的过来的用户名和密码
sprintf(user_info,"%s %s\n",buf->name,buf->data);//打印输出到user_info数组中
FILE *fp = fopen("user.txt","r");
if (fp!=NULL)//文件打开成功
{
while(fgets(name_passwd,sizeof(name_passwd),fp) != NULL)
{
if(strcmp(name_passwd,user_info) == 0)//用户名和密码匹配
{
printf("登陆成功");
menu1();
}
printf("登陆错误,密码或者账号有问题\n");
printf("按ESC退回菜单");
exit_menu2();
}
}
}
void menu1()//显示菜单1进入加减法的菜单
{
printf("---------------------------------------------- |\n");
printf("|(现练习%d个题目,对了%d个,错了%d个) |\n",count,count_true,count_false);//显示现在的问题总数,正确个数和错误个数
printf("| |\n");
printf("| |\n");
printf("|------------欢迎来到CAI计算系统---------------|\n");
printf("| |\n");
printf("| |\n");
printf("| |\n");
printf("|**********按1进入加法计算*********************|\n");
printf("|**********************************************|\n");
printf("|**********按2进入减法计算*********************|\n");
printf("|**********************************************|\n");
printf("|**********按3进入乘法计算*********************|\n");
printf("|**********************************************|\n");
printf("|**********按4进入除法计算*********************|\n");
printf("|**********************************************|\n");
printf("|**********按5进入四则混合法计算***************|\n");
printf("|**********************************************|\n");
printf("|**********按6退回登陆界面*********************|\n");
printf("|**********************************************|\n");
printf("|**********按其他键退出************************|\n");
printf("|----------------------------------------------|\n");
printf("请输入选项: ");
int i;
scanf("%d",&i);
switch(i)
{
case 1:add();//加法计算
case 2:sub();//减法计算
case 3:muti();//乘法计算
case 4:div();//除法计算
case 5:mix();//混合计算
case 6:
{
system("cls");//清屏函数
menu2();//退出到上一个界面menu2
}
default:exit(0);
}
}
void menu2()//进入登陆界面
{
printf("---------------------------------------------- |\n");
printf("|*********欢迎使用DELI心算CAI系统************* |\n");
printf("| |\n");
printf("| |\n");
printf("|----------------------------------------------|\n");
printf("| 1.按1开始注册 |\n");
printf("|--------------------------------------------- |\n");
printf("| 2.按2开始登陆 |\n");
printf("|--------------------------------------------- |\n");
printf("| 3.按任意键退出该系统 |\n");
printf("|--------------------------------------------- |\n");
printf("请输入选项: ");
int i;
scanf("%d",&i);
user buf;//定义一个结构体
switch(i)
{
case 1:do_regsite(&buf);//登陆函数
case 2:do_login(&buf);//注册函数
default:exit(0); //退出函数
}
}
//加法运算
void add()
{
printf("*******欢迎进入加法计算********\n");
loop:
enter_advance();//判断是否进入进阶运算
int b=rand()/101;//产生三位数以下的随机数
int a = rand()/101;//产生三位数以下的随机数
int c=a+b;
printf("****************共练习%d,正确%d,错误%d********************\n",count,count_true,count_false);
printf(" %d + %d = ",a,b);
exit_menu1();//随时可以退出
count++;
int i;
scanf("%d",&i);
save_add(a,b,c);
if (i==a+b)
{
printf("恭喜你答对了\n");
count_true++;
goto loop;
}
else
{
printf("很遗憾你回答错误请在回答一遍\n");
count_false++;
Beep(523,500);
printf(" %d + %d = ",a,b);
exit_menu1();//随时可以退出
int i;
scanf("%d",&i);
if (i==a+b)
{
printf("恭喜你答对了");
printf("下一题");
goto loop;
}
else
{
printf("很遗憾又答错了正确答案如下\n");
printf(" %d + %d = %d \n",a,b,a+b);
printf("下一题\n") ;
goto loop;
}
}
}
//减法运算
void sub()
{
printf("*******欢迎进入减法计算********\n");
int d;
loop:
enter_advance();
int b=rand()/101;//产生三位数以下的随机数
int a = rand()/101;//产生三位数以下的随机数
if (b>a)
{
d=b;
b=a;
a=d;
}
int c=a-b;
save_sub(a,b,c);
printf("****************共练习%d,正确%d,错误%d********************\n",count,count_true,count_false);
printf(" %d - %d = ",a,b);
exit_menu1();//随时可以退出
count++;
int i;
scanf("%d",&i);
if (i==a-b)
{
printf("恭喜你答对了");
count_true++;
goto loop;//回到循环的标注
}
else
{
printf("很遗憾你回答错误请在回答一遍\n");
count_false++;
Beep(523,500);
printf(" %d - %d = ",a,b);
exit_menu1();//随时可以退出
int i;
scanf("%d",&i);
if (i==a-b)
{
printf("恭喜你答对了");
goto loop;//回到循环的标注
}
else
{
printf("很遗憾又答错了正确答案如下\n");
printf(" %d + %d = %d \n",a,b,a-b);
goto loop;//回到循环的标注
}
}
}
//乘法计算
void muti()
{
printf("*******欢迎进入乘法计算********\n");
char c=0;
loop:
enter_advance();
int b=rand()/1000;//产生三位数以下的随机数
int a = rand()/1000;//产生三位数以下的随机数
int d=a*b;
save_muti(a,b,d);
printf("****************共练习%d,正确%d,错误%d********************\n",count,count_true,count_false);
printf(" %d * %d = ",a,b);
exit_menu1();//随时可以退出
count++;
int i;
scanf("%d",&i);
if (i==a*b)
{
printf("恭喜你答对了");
count_true++;
goto loop;//回到循环的标注
}
else
{
printf("很遗憾你回答错误请在回答一遍\n");
count_false++;
Beep(523,500);
printf(" %d * %d = ",a,b);
exit_menu1();//随时可以退出
int i;
scanf("%d",&i);
if (i==a*b)
{
printf("恭喜你答对了");
goto loop;//回到循环的标注
}
else
{
printf("很遗憾又答错了正确答案如下\n");
printf(" %d * %d = %d \n",a,b,a*b);
goto loop;//回到循环的标注
}
}
}
//除法计算
void div()
{
printf("*******欢迎进入除法计算********\n");
char c=0;
loop:
enter_advance();
int b=rand()/1000;//产生三位数以下的随机数
int a = rand()/1000;//产生三位数以下的随机数
int d=b*a;
if (d==0)
{
goto loop;//回到循环的标注
}
save_div(d,a,b);
printf("****************共练习%d,正确%d,错误%d********************\n",count,count_true,count_false);
printf(" %d / %d = ",d,a);
exit_menu1();//随时可以退出
count++;
int i;
scanf("%d",&i);
if (i==b)
{
printf("恭喜你答对了");
count_true++;
goto loop;//回到循环的标注
}
else
{
printf("很遗憾你回答错误请在回答一遍\n");
count_false++;
Beep(523,500);
printf(" %d / %d = ",d,a);
exit_menu1();//随时可以退出
int i;
scanf("%d",&i);
if (i==b)
{
printf("恭喜你答对了");
goto loop;//回到循环的标注
}
else
{
printf("很遗憾又答错了正确答案如下\n");
printf(" %d * %d = %d \n",d,a,b);
goto loop;//回到循环的标注
}
}
}
//混合运算计算(只有两个符号)
void mix()
{
printf("*******欢迎进入混合运算计算********\n");
loop:
srand((unsigned)time(NULL));
/*
flag1和flag2是混合运算的符号标志
如果flag2和flag1为00,则为/和-
如果flag2和flag1为01,则为/和+
如果flag2和flag1为11,则为*和+
如果flag2和flag1为10,则为*和-
有些产生负数和不能整除的结果全都排除
用if来判断,以及算法来去除
*/
int flag1 = rand()%2;
int flag2 = rand()%2;
int flag3;
int d;
int e;
int b=rand()/1000;
int a = rand()/1000;
int c = rand()/1000;
if (flag1==1&&flag2==1)
{
flag3=0;
printf(" %d * %d + %d= ",a,b,c);
}
if (flag1==1&&flag2==0)//为了适应小学生的难度,将所有的除法变成整除
{
flag3=1;
if (b>a)
{
d=b;
b=a;
a=d;
}
e=(a-b)*c;
if (e==0)
{
goto loop;//回到循环的标注
}
printf(" %d / %d + %d= ",e,c,b);
}
if (flag1==0&&flag2==1)
{
flag3=2;
if (a*b-c<0)//如果计算结果为负数则重新生成计算式
{
goto loop;//回到循环的标注
}
printf(" %d * %d - %d= ",a,b,c);
}
if (flag1==0&&flag2==0)
{
flag3=3;
e=(a+b)*c;
printf(" %d / %d - %d= ",e,c,b);
}
count++;
exit_menu1();//随时可以退出
int i;
scanf("%d",&i);
if (flag3==0)
{
save_mix0(a,b,c);
if (i==a*b+c)
{
printf("恭喜你答对了\n");
printf("****************共练习%d,正确%d,错误%d********************\n",count,count_true,count_false);
printf("下一道\n");
count_true++;
goto loop;//回到循环的标注
}
else
{
printf("很遗憾你回答错误请在回答一遍\n");
count_false++;
Beep(523,500);
printf(" %d * %d + %d= ",a,b,c);
exit_menu1();//随时可以退出
int i;
scanf("%d",&i);
if (i==a*b+c)
{
printf("恭喜你答对了\n");
printf("****************共练习%d,正确%d,错误%d********************\n",count,count_true,count_false);
printf("下一道\n");
goto loop;//回到循环的标注
}
else
{
printf("很遗憾又答错了正确答案如下\n");
printf(" %d * %d + %d=%d \n",a,b,c,a*b+c);
printf("****************共练习%d,正确%d,错误%d********************\n",count,count_true,count_false);
printf("下一道\n");
goto loop;//回到循环的标注
}
}
}
if (flag3==1)
{
save_mix1(e,c,b);
if (i==a)
{
printf("恭喜你答对了\n");
printf("****************共练习%d,正确%d,错误%d********************\n",count,count_true,count_false);
printf("下一道\n");
count_true++;
goto loop;//回到循环的标注
}
else
{
printf("很遗憾你回答错误请在回答一遍\n");
count_false++;
Beep(523,500);
printf(" %d / %d + %d= ",e,c,b);
exit_menu1();//随时可以退出
int i;
scanf("%d",&i);
if (i==a)
{
printf("恭喜你答对了\n");
goto loop;//回到循环的标注
}
else
{
printf("很遗憾又答错了正确答案如下\n");
printf(" %d / %d + %d=%d \n",e,c,b,a);
exit_menu1();//随时可以退出
printf("****************共练习%d,正确%d,错误%d********************\n",count,count_true,count_false);
printf("下一道\n");
goto loop;//回到循环的标注
}
}
}
if (flag3==2)
{
save_mix2(a,b,c);
if (i==a*b-c)
{
printf("恭喜你答对了\n");
count_true++;
goto loop;//回到循环的标注
}
else
{
printf("很遗憾你回答错误请在回答一遍\n");
count_false++;
Beep(523,500);
printf(" %d * %d - %d= ",a,b,c);
exit_menu1();//随时可以退出
int i;
scanf("%d",&i);
if (i==a*b-c)
{
printf("恭喜你答对了\n");
goto loop;//回到循环的标注
}
else
{
printf("很遗憾又答错了正确答案如下\n");
printf(" %d * %d - %d=%d \n",a,b,c,a*b-c);
printf("****************共练习%d,正确%d,错误%d********************\n",count,count_true,count_false);
printf("下一道\n");
goto loop;//回到循环的标注
}
}
}
if (flag3==3)
{
save_mix1(e,c,b);
if (i==a)
{
printf("恭喜你答对了\n");
printf("****************共练习%d,正确%d,错误%d********************\n",count,count_true,count_false);
printf("下一道\n");
count_true++;
goto loop;//回到循环的标注
}
else
{
printf("很遗憾你回答错误请在回答一遍\n");
count_false++;
Beep(523,500);
printf(" %d / %d - %d= ",e,c,b);
exit_menu1();//随时可以退出
int i;
scanf("%d",&i);
if (i==a)
{
printf("恭喜你答对了\n");
printf("****************共练习%d,正确%d,错误%d********************\n",count,count_true,count_false);
printf("下一道\n");
goto loop;//回到循环的标注
}
else
{
printf("很遗憾又答错了正确答案如下\n");
printf(" %d / %d - %d=%d \n",e,c,b,a);
printf("****************共练习%d,正确%d,错误%d********************\n",count,count_true,count_false);
printf("下一道\n");
goto loop;//回到循环的标注
}
}
}
}
//离开菜单1
void exit_menu1()
{
char c=getch();
if (c==27)
{
system("cls");//清屏函数
menu1();//退出到上一个界面menu1
}
}
//离开菜单2
void exit_menu2()
{
char c=getch();
if (c==27)
{
system("cls");//清屏函数
menu2();//退出到上一个界面menu2
}
}
//多次练习之后会提示你是否进入进阶训练(混合计算)
void enter_advance()
{
if (count==COUNT)
{
if (count_true>COUNT_TRUE)
{
printf("你是否想进行进阶运算(想就按y,其他按键继续运算)\n");
char c=getch();
if(c==121)
{
mix();
}
}
}
}
void save_add(int a,int b,int c)//储存加法
{
FILE *fp=fopen("count.txt","a+");//创建一个指针
fprintf(fp,"%d + %d = %d \n",a,b,c);//将算式存入文件中
fclose(fp);
}
void save_sub(int a,int b,int c)//储存减法
{
FILE *fp=fopen("count.txt","a+");//创建一个指针
fprintf(fp,"%d - %d = %d \n",a,b,c);//将算式存入文件中
fclose(fp);
}
void save_muti(int a,int b,int c)//储存乘法
{
FILE *fp=fopen("count.txt","a+");//创建一个指针
fprintf(fp,"%d - %d = %d \n",a,b,c);//将算式存入文件中
fclose(fp);
}
void save_div(int a,int b,int c)//储存除法
{
FILE *fp=fopen("count.txt","a+");//创建一个指针
fprintf(fp,"%d - %d = %d \n",a,b,c);//将算式存入文件中
fclose(fp);
}
void save_mix0(int a,int b,int c)//储存混合运算0
{
FILE *fp=fopen("count.txt","a+");//创建一个指针
int i;
i=a*b+c;
fprintf(fp,"%d * %d + %d = %d \n",a,b,c,i);//将算式存入文件中
fclose(fp);
}
void save_mix1(int a,int b,int c)//储存混合运算4
{
FILE *fp=fopen("count.txt","a+");//创建一个指针
int i;
i=a/b+c;
fprintf(fp,"%d * %d + %d = %d \n",a,b,c,i);//将算式存入文件中
fclose(fp);
}
void save_mix2(int a,int b,int c)//储存混合运算2
{
FILE *fp=fopen("count.txt","a+");//创建一个指针
int i;
i=a*b-c;
fprintf(fp,"%d * %d + %d = %d \n",a,b,c,i);//将算式存入文件中
fclose(fp);
}
void save_mix3(int a,int b,int c)//储存混合运算3
{
FILE *fp=fopen("count.txt","a+");//创建一个指针
int i;
i=a/b-c;
fprintf(fp,"%d * %d + %d = %d \n",a,b,c,i);//将算式存入文件中
fclose(fp);
}