一、实现代码
#include <iostream>
#include <string>
#include <time.h>
#include <stdlib.h>
#include <sstream>
#include <fstream>
using namespace std;
void denglu(); //用户登录函数,账号密码见文档
void produce(); //试卷生成函数
void qiehuan(); //切换类型函数
void ming(); // 文档命名,具体为 "用户名+年级+年-月-日-时-分-秒.txt"
int num; //生成题目数量
int caozuo; //操作数
int n1;
int n2;
int n3;
int i;
int number;
int yunsuan;
int xuhao=0;
string ID;
string passward;
string grade;
string path;
string lujing;
string gradeswitch;
stringstream exam; //试卷内容
ofstream txt;
void denglu()
{
while(1)
{
cout<<"请输入用户名和密码(账号与密码间以空格隔开):";
cin>>ID>>passward;
if(ID=="张三1"||ID=="张三2"||ID=="张三3")
{
if(passward=="123")
{
grade="小学";
break;
}
}
else if(ID=="李四1"||ID=="李四2"||ID=="李四3")
{
if(passward=="123")
{
grade="初中";
break;
}
}
else if(ID=="王五1"||ID=="王五2"||ID=="王五3")
{
if(passward=="123")
{
grade="高中";
break;
}
}
cout<<"请输入正确的用户名、密码!"<<endl<<endl;
}
cout<<endl<<"当前选择为"<<grade<<"出题"<<endl<<endl;
path="C:\\Users\\86189\\Desktop\\试卷生成\\生成试卷";
ming();
produce();
}
void produce()
{
cout<<"请输入生成题目数量(输入-1将退出当前用户,重新登录):";
cin>>num;
while(num>30||num<10)
{
if(num==-1)
{
cout<<"您已退出,请重新登录!"<<endl<<endl;
denglu();
}
else cout<<"输入的题目数量无效,请重新输入:";
cin>>num;
}
txt.open(lujing.c_str()); //编写试卷美内容
txt<<"这是一张"<<grade<<"卷子,共有"<<num<<"道题目。"<<endl<<endl;
for(num;num!=0;num--) //出多少题
{
bool flag=false;
caozuo=rand()%5+1;
if(grade=="小学")
{
caozuo=rand()%4+2;
}
n1=caozuo;
n2=0;
n3=0;
if(caozuo>2&&rand()%2==0)
{
if(caozuo==3)
{
n2=rand()%2+1;
n3=2;
}
else if(caozuo==4)
{
n2=rand()%3+1;
if(n2==3) n3=2;
else n3=rand()%2+2;
}
else if(caozuo==5)
{
n2=rand()%4+1;
if(n2==4) n3=2;
else if(n2==3) n3=rand()%2+2;
else n3=rand()%3+2;
}
}
while(n1>0)
{
n1--;
if(n1==caozuo-n2) exam<<"(";
if(grade=="小学") yunsuan=0;
else if(grade=="初中")
{
yunsuan=rand()%3;
if(yunsuan>0) flag=true;
if(n1==0&&flag==false) yunsuan=rand()%2+1;
} else if(grade=="高中")
{
yunsuan=rand()%6;
if(yunsuan>2) flag=true;
if(n1==0&&flag==false) yunsuan=rand()%3+3;
}
number=rand()%100+1;
switch(yunsuan)
{
case 0:
exam<<number;
break;
case 1:
exam<<number<<"^2";
break;
case 2:
exam<<"√"<<number;
break;
case 3:
exam<<"sin"<<number<<"°";
break;
case 4:
exam<<"cos"<<number<<"°";
break;
case 5:
exam<<"tan"<<number<<"°";
break;
}
if(n1==caozuo-n2-n3+1)exam<<")";
if(n1!=0)
{
i=rand()%4;
switch(i)
{
case 0:
exam<<"+";
break;
case 1:
exam<<"-";
break;
case 2:
exam<<"*";
break;
case 3:
exam<<"/";
break;
}
}
else exam<<"=";
}
exam<<endl;
xuhao++;
txt<<xuhao<<"."<<" "<<exam.str()<<endl;
exam.str("");
}
txt.close();
cout<<endl<<"您已成功生成试卷!"<<endl;
}
void qiehuan()
{
while(1)
{
cout<<endl<<"若需要切换类型,请输入\"切换为XX\",不需要则输入\"否\",退出登录请输入\"-1\""<<endl;
cout<<":";
cin>>gradeswitch;
if(gradeswitch=="否")
{
ming();
produce();
}
else if(gradeswitch=="-1") break;
else if(gradeswitch=="切换为小学"||gradeswitch=="切换为初中"||gradeswitch=="切换为高中")
{
grade=gradeswitch.erase(0,6);
ming();
produce();
}
else
{
while(1)
{
cout<<"请输入小学、初中和高中三个选项中的一个:";
cin>>gradeswitch;
if(gradeswitch=="小学"||gradeswitch=="初中"||gradeswitch=="高中")
{
grade=gradeswitch;
ming();
produce();
break;
}
else if(gradeswitch=="-1") break;
}
}
if(gradeswitch=="-1") break;
}
cout<<"已退出本次登录!"<<endl;
}
void ming()
{
char ming[100];
struct tm *ptr;
time_t It=time(NULL);
ptr=localtime(&It);
strftime(ming,30,"%y-%m-%d-%H-%M-%S.txt",ptr);
if(ID=="张三1"||ID=="张三2"||ID=="张三3"){lujing=path+"\\"+"小学试卷\\"+ID+grade+ming;}
if(ID=="李四1"||ID=="李四2"||ID=="李四3"){lujing=path+"\\"+"初中试卷\\"+ID+grade+ming;}
if(ID=="王五1"||ID=="王五2"||ID=="王五3"){lujing=path+"\\"+"高中试卷\\"+ID+grade+ming;}
}
int main()
{
srand((int)time(0));
denglu();
qiehuan();
return 0;
}
二、代码分析
1.在本代码中,使用了大家都能理解的编程方法,通过void定义函数,在main函数中通过引用函数实现代码功能
2.使用了frsteam实现试卷txt的编写输出,以及stringstream实现试卷内容的输入
3.试卷生成中采用了从整体到局部的方法,先寻找了三种试卷的共通点,再从不同点着手,在三种不同试卷中,(),+,-,*,/,=以及操作数数量的限制是共通的
4.将一些输入文本放入试卷生成函数中,方便切换功能使用时有正常的文本输出
5.看完之后的一个小问题:为什么将加减乘除和平方,开方,三角函数分开,既然分开了为什么不把平方,开方和三角函数也分开,从而区分小学,初中和高中
三、功能实现
实现基本完备,试卷可以正常生成,且命名为实时时间,试卷内容实现完全,能完美生成对应阶段的数学试卷,但唯一美中不足的是没有实现查重功能
四、优点
代码浅显易懂,采用void定义函数并在main程序中引用;试卷生成的思路很好,有从整体到局部的思路想法;功能实现较为完备,试卷均能正常生成;对于代码分析中的小问题,为什么不将加减乘除和其他几项合在一起?经编写者解答,与两个原因,一是因为加减乘除和等号是三种试卷都会使用到的东西,算是共通点,而其他不是,所以可以单独摘出当作整体来写,二是因为加减乘除运算符的特殊性,如果放在一起,因为操作数数字和运算符的先后顺序不一,所以在加右括号时,就不能保证括号在正确的位置,可能在符号后,所以单独摘出
五、缺点
没有实现查重试卷的功能;由于定义函数变量过多,可能不太能明了每个代指什么。
原文:https://www.cnblogs.com/Faith-123/p/15350808.html