一个小学算术自测系统,功能实现,用户注册、登录、四则运算随机产生(其中加减法采用总分排名制,在多次进行测试后,能够分别给出加减法的总分排名以及输出最高最低分),乘除法采用通关制进行挑战,评价功能、退出功能等
唯一不足的就是C语言基础不行,对于指针的使用不熟悉,使用了全局变量,系统优化度不高
看一下运行时的样子。
代码块
头文件
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <windows.h>
#include <string.h>
#include <conio.h>
#define LEN 50
函数声明,全局变量声明以及结构体定义
void color(short x);//颜色声明
void Login(); //系统登录界面声明
void Foreword(); //前言界面声明
void Menu() ; //菜单声明
void Add(); //加法
void Sub(); //减法界面
void Inform();
void Eva();
void Addzong(int n,int cnt); //计算加法正确率以及得分和等级函数 ,n是输入题目数,cnt是答对题数
void Subzong(int n,int cnt); //计算减法正确率以及得分和等级函数 ,n是输入题目数,cnt是答对题数
void Mul(); //乘法
int Mul1();
int Mul2();
int Mul3();
void Div(); //除法
int Div1();
int Div2();
int Div3();
void Seq(float a[],int m); //排序
void Rank(); //排名
void HideCursor(); //隐藏光标
void Gotoxy(int x, int y); //光标移动
void DrawBox();//画边框
void jiazai();//加载界面声明
void result(int m,int s);
void zong(int n,int cnt);
void Create_File();
void registers();
int Input_login();
typedef struct The_users //typedef 可以定义结构体别名
{
char id[11]; //账号
char pwd[20]; //密码
}users;
int cnt=0,iadd=0,isub=0,summ[10];
float add[100],sub[100];
主函数
int main()
{
Login();
jiazai();
Foreword();
system("cls");
Menu();
bool flag=TRUE;
while(flag)
{
Menu();
}
}
登录界面函数
void Login() //登录界面
{
Create_File;
int c,a;
do{
system("cls");
system("color 80");
printf("\t\t ----------------------------------------------------------------------------\n");
printf("\t\t ----------------------------------------------------------------------------\n\n\n");
printf("\t\t\t\t\t C语言程序设计项目案例\n");
printf("\t\t\t\t ╔═══════════════════════════════╗\n");
printf("\t\t\t\t ║ 名称:小学生算术自测系统 ║\n");
printf("\t\t\t\t ║ 工具:C-Free4.0 C语言 ║\n");
printf("\t\t\t\t ║ 作者:十四小组 ║\n");
printf("\t\t\t\t ╚═══════════════════════════════╝\n");
printf ("\t\t\t\t\t\t 1.登录账号\n");
printf ("\t\t\t\t\t\t 2.注册账号\n");
printf ("\t\t\t\t\t\t 0.退出\n");
printf ("\t\t\t\t\t\t 请选择:");
scanf ("%d", &c);
switch (c)
{
case 1:
a=Input_login();//登录
break;
case 2:
registers();//注册
break;
case 0:
exit(0);//退出
default :
printf("您输入有误!请重新输入!");
system("pause");
break;
}
}while(a!=1);
printf("\t\t\t\t\t\t欢迎进入小学生算术自测系统");
}
前言界面函数
void Foreword()//前言界面
{
char yon;
printf("【载入完成,欢迎来到小学生算术自测系统】\n");
printf("\t\t\t\t\t\t\t\t前言\n");
printf("\t本项目是应用C 语言开发的小学生算术自测系统,该系统能够通过菜单提供功能选择,能够实现简单的加法、减法、乘法和除法的随机测试。\n");
printf("\t其中加减法采取打分制度,乘除法采用通过模式,能够实现题量选择、题目批阅、答案提示、测试评价等功能;\n");
printf("\t要求熟悉基础语法知识,熟悉顺序、选择、循环三种基本程序结构,熟悉一维整型数组和字符串的存储应用,熟悉自定义函数的定义、声明和调用。\n");
printf("\t是否继续...\n");
printf("\n");
system("pause");
}
菜单界面函数
void Menu() //菜单界面
{
int xuan;
printf("\t\t 小朋友,欢迎你们来学习小学算术!☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ \n");
printf("\t\t 赶快选择你的学习内容吧!! ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ⌒_⌒\n");
printf("\n");
printf("\t\t\t\t\t\t\t主菜单\n") ;
printf("\t\t ╔════════════════════════════════════════════════════════════════════════════╗\n");
printf("\t\t ║ 1.加法 ◆ 2.减法 ◆ 3.乘法 ◆ 4.除法║\n");
printf("\t\t ║----------------------------------------------------------------------------║\n") ;
printf("\t\t ║ 5.说明 ◆ 6.评价 ◆ 7.排名 ◆ 0.退出║\n") ;
printf("\t\t ╚════════════════════════════════════════════════════════════════════════════╝\n");
printf("\n\t\t 我的选择:");
scanf("%d",&xuan) ;
system("cls");
switch(xuan)
{
case 0:exit(1);
break;
case 1:Add();
break;
case 2:Sub();
break;
case 3:Mul();
break;
case 4:Div();
break;
case 5:Inform();
break;
case 6:Eva();
break;
case 7:Rank();
break;
}
}
加法函数
void Add() //加法界面
{
clock_t start,end;
srand(time(0));
int an,a,b,m,s,n,temp;
cnt=0;
printf("小朋友,赶快进入加法测试吧!\n\n");
printf("请输入题目数量<建议在20道数左右>:");
scanf("%d",&n);
start=clock();
for(int i=1;i<=n;i++)
{
a=rand()%100;
b=rand()%100;
printf("第%d题:",i);
printf("%d+%d= \n",a,b);
m=a+b;
printf("请输入你的计算结果:");
scanf("%d",&s);
result(m,s);//调用判断正确答案函数
}
end=clock();
Addzong(n,cnt);//调用计算正确率以及得分函数
printf("用时:%.1f秒\n",(float)(end-start)*0.001);
system("pause");
system("cls");
}
减法函数
void Sub()//减法界面
{
clock_t start,end;
srand(time(0));
int an,a,b,m,s,n,temp;
printf("小朋友,赶快进入加法测试吧!\n\n");
printf("请输入题目数量<建议在20道数左右>:");
scanf("%d",&n);
cnt=0;
start=clock();
for(int i=1;i<=n;i++)
{
a=rand()%100;
b=rand()%100;
if(a<b)
{
temp=a;
b=a;
b=temp;
}
printf("第%d题:",i);
printf("%d-%d= \n",a,b);
m=a-b;
printf("请输入你的计算结果:");
scanf("%d",&s);
result(m,s);
}
end=clock();
Subzong(n,cnt);
printf("用时:%.1f秒\n\n\n",(float)(end-start)*0.001);
system("pause");
system("cls");
}
乘法界面
void Mul() //乘法函数
{
int f1,f2,f3;
do
{
f1=Mul1();
}while(f1==1);
if(f1==2)
{
do
{
f2=Mul2();
}while(f2==1);
if(f2==2)
{
do
{
f3=Mul3();
}while(f3==1);
system("pause");
system("cls");
Menu();
}
else
{
system("cls");
Menu();
}
}
else
{
system("cls");
Menu();
}
}
除法函数
void Div()//除法函数
{
int f1,f2,f3;
do
{
f1=Div1();
}while(f1==1);
if(f1==2)
{
do
{
f2=Div2();
}while(f2==1);
if(f2==2)
{
do
{
f3=Div3();
}while(f3==1);
system("pause");
system("cls");
Menu();
}
else
{
system("cls");
Menu();
}
}
else
{
system("cls");
Menu();
}
}
说明函数
void Inform()//说明函数
{
printf("关于该系统的说明\n\n\n");
printf(" 本项目是应用C语言开发的小学生算术自测系统,该系统能够通过菜单提供功能选择,能够实现简单的\n加法,减法,乘法和除法 的随机测试(其中加减法采取打分制度,在进行多次\n加减法测试后还能对其进行加减法的分别的从低到高的排名,并输出最高分\n和最低分,乘除法采取通关模式),能够实现题量选择,题目批阅,答案提示,测评评价等功能。\n");
printf(" 1:加减法采用计时计分模式,它根据分数的范围来评出ABCD四个等级,然后将每次运行程序时的每次\n的加减运算的成绩分别存储起来,最后可以在菜单界面查看,自己的分数排名和\n自己的最高分和最低分。\n");
printf(" 2:乘除法采用闯关模式,第一关是两个操作数均是一位数;第二关第一个操作数是一位数,第二个操\n作数是两位数;第三关两个操作数均是两位数;除法得到的结果如果是整数3或者\n有理数2.75,直接得出结果,如果是无理数,则保留小数点后两位(四舍五入)5.6666...输出5.67。 ");
printf("\n");
printf("\n\n\n");
system("pause");
system("cls");
}
评价函数
void Eva()//评价函数
{
int eva;
printf("您对我们的系统满意度是多少呢?\n");
printf("请对我们打分(0--10分):") ;
scanf("%d",&eva);
if(eva>=0&&eva<=5)
{
printf("谢谢参与!我们会努力改进的!\n");
}
else if(eva>=6&&eva<=10)
{
printf("谢谢鼓励!我们会继续加油的!\n");
}
system("pause");
system("cls");
}
void result(int m,int s)//判断计算输入答案是否正确
{
if(m==s)
{
printf("恭喜你答对了!\n");
cnt++;
}
else
printf("很遗憾你答错了! 正确答案应该是%d\n",m);
}
void Addzong(int n,int cnt) //计算加法正确率以及得分和等级函数 ,n是输入题目数,cnt是答对题数
{
printf("\n\n你一共答对了%d题\n",cnt);
float sum;
sum=100.0/n*cnt;
sum=(long)(sum*100+0.5);
sum/=100.0;
add[iadd]=sum;
iadd++;
if(sum>=0&&sum<60)
{
printf("得分:%.2f%.\n等级:D\n",sum);
}
else if(sum>=60&&sum<=70)
{
printf("得分:%.2f%.\n等级:C\n",sum);
}
else if(sum>70&&sum<90)
{
printf("得分:%.2f%.\n等级:B\n",sum);
}
else
printf("得分:%.2f%.\n等级:A\n",sum);
}
void Subzong(int n,int cnt) //计算减法正确率以及得分和等级函数 ,n是输入题目数,cnt是答对题数
{
printf("\n\n你一共答对了%d题\n",cnt);
float sum;
sum=100.0/n*cnt;
sum=(long)(sum*100+0.5);
sum/=100.0;
sub[isub]=sum;
isub++;
if(sum>=0&&sum<60)
{
printf("得分:%.2f%.\n等级:D\n",sum);
}
else if(sum>=60&&sum<=70)
{
printf("得分:%.2f%.\n等级:C\n",sum);
}
else if(sum>70&&sum<90)
{
printf("得分:%.2f%.\n等级:B\n",sum);
}
else
printf("得分:%.2f%.\n等级:A\n",sum);
}
加载进度条,这个有点炫酷
//加载界面 (上)
void jiazai()
{
int len;
HideCursor();
for(len = 1; len <= LEN; len++)
{
Gotoxy(2 * len, 3 );
printf("█");
Gotoxy(50, 2);
printf("已完成%d%%", 2 * len);
Sleep(50);
}
Gotoxy(50, 2);
printf("加载已完成");
system("cls");
}
//隐藏光标
void HideCursor()
{
CONSOLE_CURSOR_INFO cursor_info = {1, 0};//后边的0代表光标不可见
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
//光标移动
void Gotoxy(int x, int y)
{
HANDLE hout; //定义句柄变量hout
COORD coord; //定义结构体coord
coord.X = x;
coord.Y = y;
hout = GetStdHandle(STD_OUTPUT_HANDLE);//获得标准输出(屏幕)句柄
SetConsoleCursorPosition(hout, coord);//移动光标
}
//画边框
void DrawBox()
{
printf("╔═════════════════════════╗");
putchar('\n');
printf("║ ║");
putchar('\n');
printf("╚═════════════════════════╝");
}
//加载界面 (下)
乘除法闯关制度
int Mul1() //乘法
{
int count=0,n,answer,a,b,find=1;
char ch;
srand(time(NULL));
printf("小朋友,赶快进入乘法测试吧!\n\n");
printf("欢迎进入第一关!\n");
printf("请设定题目数量<建议在10题左右>:");
scanf("%d",&n);
do
{
answer=0;
a=rand()%10;
b=rand()%10;
printf("%d*%d=",a,b);
scanf("%d",&answer);
if (answer==(a*b))
printf("恭喜你,答对了!\n");
else
{
printf("很遗憾,答错了!\n");
find=0;
}
count++;
}while(count<n);
if (find==0)
{
printf("很遗憾,没能通过第一关!\n");
printf("是否继续挑战?Y<1>/N<0>:");
scanf(" %c",&ch);
if (ch=='Y'||ch=='1')
return 1;
else
return 0;
}
else
{
printf("恭喜通过第一关!\n");
printf("是否继续挑战?Y<1>/N<0>:");
scanf(" %c",&ch);
if (ch=='Y'||ch=='1')
return 2;
else
return 0;
}
}
int Mul2()
{
int count=0,n,answer,a,b,find=1;
char ch;
srand(time(NULL));
printf("欢迎进入第二关!\n");
printf("请设定题目数量<建议在10题左右>:");
scanf("%d",&n);
do
{
answer=0;
a=rand()%10;
b=rand()%90+10;
printf("%d*%d=",a,b);
scanf("%d",&answer);
if (answer==(a*b))
printf("恭喜你,答对了!\n");
else
{
printf("很遗憾,答错了!\n");
find=0;
}
count++;
}while(count<n);
if (find==0)
{
printf("很遗憾,没能通过第二关!\n");
printf("是否继续挑战?Y<1>/N<0>:");
scanf(" %c",&ch);
if (ch=='Y'||ch=='1')
return 1;
else
return 0;
}
else
{
printf("恭喜通过第二关!\n");
printf("是否继续挑战?Y<1>/N<0>:");
scanf(" %c",&ch);
if (ch=='Y'||ch=='1')
return 2;
else
return 0;
}
}
int Mul3()
{
int count=0,n,answer,a,b,find=1;
char ch;
srand(time(NULL));
printf("欢迎进入第三关!\n");
printf("请设定题目数量<建议在5题左右>:");
scanf("%d",&n);
do
{
answer=0;
a=rand()%90+10;
b=rand()%90+10;
printf("%d*%d=",a,b);
scanf("%d",&answer);
if (answer==(a*b))
printf("恭喜你,答对了!\n");
else
{
printf("很遗憾,答错了!\n");
find=0;
}
count++;
}while(count<n);
if (find==0)
{
printf("很遗憾,没能通过第三关!\n");
printf("是否继续挑战?Y<1>/N<0>:");
scanf(" %c",&ch);
if (ch=='Y'||ch=='1')
return 1;
else
return 0;
}
else
{
printf("恭喜通过第三关!\n");
printf("恭喜闯关成功!\n");
return 0;
}
}
int Div1() //除法
{
int count=0,n,a,b,find=1;
char ch;
float answer,result;
srand(time(NULL));
printf("小朋友,赶快进入除法测试吧!\n\n");
printf("欢迎进入第一关!\n");
printf("请设定题目数量<建议在10题左右>:");
scanf("%d",&n);
do
{
answer=0;
a=rand()%10;
b=rand()%9+1;
printf("%d/%d=",a,b);
scanf("%f",&answer);
result=(long)((float)a/b*100+0.5);
result/=100.0;
if (fabs(result-answer)<1.0e-5)
printf("恭喜你,答对了!\n");
else
{
printf("很遗憾,答错了!\n");
find=0;
}
count++;
}while(count<n);
if (find==0)
{
printf("很遗憾,没能通过第一关!\n");
printf("是否继续挑战?Y<1>/N<0>:");
scanf(" %c",&ch);
if (ch=='Y'||ch=='1')
return 1;
else
return 0;
}
else
{
printf("恭喜通过第一关!\n");
printf("是否继续挑战?Y<1>/N<0>:");
scanf(" %c",&ch);
if (ch=='Y'||ch=='1')
return 2;
else
return 0;
}
}
int Div2()
{
int count=0,n,a,b,find=1;
char ch;
float answer,result;
srand(time(NULL));
printf("欢迎进入第二关!\n");
printf("请设定题目数量<建议在10题左右>:");
scanf("%d",&n);
do
{
answer=0;
a=rand()%90+10;
b=rand()%9+1;
printf("%d/%d=",a,b);
scanf("%f",&answer);
result=(long)((float)a/b*100+0.5);
result/=100.0;
if (fabs(result-answer)<1.0e-5)
printf("恭喜你,答对了!\n");
else
{
printf("很遗憾,答错了!\n");
find=0;
}
count++;
}while(count<n);
if (find==0)
{
printf("很遗憾,没能通过第二关!\n");
printf("是否继续挑战?Y<1>/N<0>:");
scanf(" %c",&ch);
if (ch=='Y'||ch=='1')
return 1;
else
return 0;
}
else
{
printf("恭喜通过第二关!\n");
printf("是否继续挑战?Y<1>/N<0>:");
scanf(" %c",&ch);
if (ch=='Y'||ch=='1')
return 2;
else
return 0;
}
}
int Div3()
{
int count=0,n,a,b,find=1;
char ch;
float answer,result;
srand(time(NULL));
printf("欢迎进入第三关!\n");
printf("请设定题目数量<建议在5题左右>:");
scanf("%d",&n);
do
{
answer=0;
a=rand()%90+10;
b=rand()%90+10;
printf("%d/%d=",a,b);
scanf("%f",&answer);
result=(long)((float)a/b*100+0.5);
result/=100.0;
if (fabs(result-answer)<1.0e-5)
printf("恭喜你,答对了!\n");
else
{
printf("很遗憾,答错了!\n");
find=0;
}
count++;
}while(count<n);
if (find==0)
{
printf("很遗憾,没能通过第三关!\n");
printf("是否继续挑战?Y<1>/N<0>:");
scanf(" %c",&ch);
if (ch=='Y'||ch=='1')
return 1;
else
return 0;
}
else
{
printf("恭喜通过第三关!\n");
printf("恭喜闯关成功!\n");
return 0;
}
}
对成绩进行排名并且输出最高分最低分
void Seq(float a[],int m)//对成绩进行选择排序 ,输出最高分以及最低分,a[]是总分数组,m是数组里总分的个数
{
int i,j,k;
float temp;
for(i=0;i<m-1;i++)
{
k=i;
for(j=k+1;j<m;j++)
{
if(a[j]<a[k])
{
k=j;
}
if (k!=i)
{
temp=a[k];
a[k]=a[i];
a[i]=temp;
}
}
}//选择排序法
for(i=0;i<m;i++)
{
printf("\t%.2f\n",a[i]);
}
printf("最高分: %.2f , 最低分: %.2f\n",a[m-1],a[0]);
}
void Rank()
{
printf("加法排名(由低到高): \n");
Seq(add,iadd);//调用排序函数 ,由高到低输出分数,同时输出最高分和最低分
printf("\n\n减法排名(由低到高):\n");
Seq(sub,isub); //调用排序函数 ,由高到低输出分数,同时输出最高分和最低分
printf("\n");
system("pause");
system("cls");
}
登录系统所调用的函数,其中用到了文件结构体相关知识
void Create_File()
{
FILE *fp;
if ((fp = fopen("ddddd.txt","rb"))==NULL) //以二进制读的方式打开文件判断是否能打开 /*如果此文件不存在*/
{
if ((fp = fopen("ddddd.txt","wb+"))==NULL)//以二进制写的方式打开文件判断是否能打开
{
printf("无法建立文件!\n");
exit(0);
}
}
}
void registers() //按结构体的大小,一次写入或者读入1个结构体大小,注册账号和密码
{
users a,b;//结构体 The_users 重命名定义,定义两个变量
FILE *fp;
char temp[20];
int count = 0;
printf("\t\t\t\t\t\t欢迎来到注册界面!\n");
Sleep(1000);//停顿1秒
fp = fopen("ddddd.txt","r");//以读的方式打开文件
fread(&b, sizeof(struct The_users), 1, fp); //读入一个结构体字符块 到b
printf("\t\t\t\t\t\t请输入账号:");
scanf("%s",&a.id);
while (1)
{
if (strcmp(a.id, b.id)) /*如果两串不相等*/
{
if (!feof(fp)) /*如果未到文件尾*///feof()判断是否读到文件末尾
{
fread(&b, sizeof(struct The_users), 1, fp);
}
else
break;
}
else
{
printf("\t\t\t\t\t\t 此用户名已存在!请重新注册!");
Sleep(1000);
fclose(fp);
return;
}
}
printf("\t\t\t\t\t\t 请输入密码:");
scanf(" %s",&a.pwd);
printf("\t\t\t\t\t\t 请确认密码:");
scanf(" %s",&temp);
do{
if(!strcmp(a.pwd,temp)){
fp = fopen("ddddd.txt","a");
fwrite(&a, sizeof(struct The_users), 1, fp);
printf("\t\t\t\t\t\t 账号注册成功,请登录!\n");
Sleep(500);
fclose(fp);
return;
}else{
printf("\t\t\t\t\t\t 两次密码不匹配!请重新输入!\n");
scanf("%s",&a.pwd);
printf("\t\t\t\t\t\t 请确认密码\n");
scanf("%s",&temp);
}
}while(1);
}
int Input_login()
{
int pp=0,ppp=1;
users a,b;//定义结构体The_users别名
FILE *fp;
printf("\n\t\t\t\t\t\t 欢迎来到登录界面!\n");
Sleep(1000);
fp = fopen("ddddd.txt","r");
fread(&b, sizeof(struct The_users), 1, fp); //读入一个结构体字符块 写入b
printf("\t\t\t\t\t\t 请输入账号:");
scanf("%s",&a.id);
while (1)
{
if (strcmp(a.id, b.id)==0) //如果有此用户名
{
break;
}
else
{
if (!feof(fp)) //如果文件没有读完
{
fread(&b, sizeof(struct The_users), 1, fp);
}
else
{
printf("\t\t\t\t\t\t 此用户名不存在,请重新输入!\n");
Sleep(500);
fclose(fp);
return 0;
}
}
}
printf("\t\t\t\t\t\t 请输入密码:");
scanf("%s",&a.pwd);
do{
if (strcmp(a.pwd, b.pwd)==0) /*如果密码匹配*/
{
fclose(fp);
//printf("登录成功,欢迎使用!");
break;
}
else
{
pp++;
if(pp==1)
{
printf("\t\t\t\t\t\t 密码不正确!请重新输入密码:");
scanf("%s",&a.pwd);
ppp=0;
}
else if(pp==2)
{
printf("\t\t\t\t\t\t 密码不正确!你还有两次机会:");
scanf("%s",&a.pwd);
ppp=0;
}
else if(pp==3)
{
printf("\t\t\t\t\t\t 密码不正确!你还有一次机会:");
scanf("%s",&a.pwd);
ppp=0;
}
else
{
printf("\t\t\t\t\t\t 密码不正确!请10秒后重新登录!!!\n");
printf("\t\t\t\t\t\t ");
Sleep(10000) ;
pp=4;
break;
}
}
}while(strcmp(a.pwd, b.pwd)!=0);
if(pp==4)
{
system("cls");
Login();
}
else
{
if(ppp==0)
{
printf("\t\t\t\t\t\n登陆成功!\n\n\n");
}
}
return 1;
}
void color(short x) //自定义函根据参数改变颜色
{
if(x>=0 && x<=15)//参数在0-15的范围颜色
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x); //只有一个参数,改变字体颜色
else//默认的颜色白色
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}