1、问题描述
设计一个单项选择题标准化考试系统,该系统要求能自动组卷和评分。
2、功能要求
(1)用文件保存试题库(每个试题包括题干、4 个备选答案、标准答案)
(2)试题录入:可随时增加试题到试题库中。
(3)试题抽取:每次从试题库中可以随机抽取 N 道题(N 由键盘输入)。
(4)答题:用户可实现输入自己的答案。
(5)自动判卷:系统可根据用户答案与标准答案的比对实现判卷并给出成绩。
(6)退出。
代码:
#include <iostream>
#include<vector>
#include<fstream>
#include<string>
#include <algorithm>
#include <random>
#include <ctime>
#include <time.h>
#define FILENAME "problems.txt"
#define FILENAME2 "users.txt"
#define random(x) (rand()%x)
using namespace std;
void showMenu1()
{
cout << "******************************" << endl;
cout << "******* 考 试 系 统 ******" << endl;
cout << "******* 考试请按 1 ******" << endl;
cout << "******* 整理题库请按 2 ******" << endl;
cout << "******* 退出请按 0 ******" << endl;
cout << "******************************" << endl;
}
void showMenu2()
{
cout << "*********************************" << endl;
cout << "******* 考 试 系 统 ******" << endl;
cout << "******* 出题请按 1 ******" << endl;
cout << "******* 保存题库请按 2 ******" << endl;
cout << "******* 退出请按 0 ******" << endl;
cout << "*********************************" << endl;
}
void showMenu3() {
cout << "*********************************" << endl;
cout << "******* 考 试 系 统 ******" << endl;
cout << "******* 登录请按 1 ******" << endl;
cout << "******* 注册请按 2 ******" << endl;
cout << "******* 退出请按 0 ******" << endl;
cout << "*********************************" << endl;
}
class Timu {
public:
string tigan;
string A, B, C, D;
char answer;
void show() {
cout << tigan << endl;
cout << "A." << A << endl;
cout << "B." << B << endl;
cout << "C." << C << endl;
cout << "D." << D << endl;
}
};
class User {
public:
string password;
string userName;
};
void save(vector<Timu>& a)
{
ofstream ofs;
ofs.open(FILENAME, ios::out);
for (auto& i : a) {//录入每道题信息
ofs << i.tigan << "\n" << i.A << "\n" << i.B << "\n"
<< i.C << "\n" << i.D << "\n" << i.answer << endl;
//将所有信息存储
}
cout << "保存成功" << endl;
ofs.close();//关闭文件
}
void fetch(vector<Timu>& a)
{
ifstream ifs;
ifs.open(FILENAME, ios::in);//读文件
if (!ifs.is_open())//判断是否存在
{
cout << "题库文件不存在" << endl;
ifs.close();
return;
}
Timu i;
while (ifs >> i.tigan >> i.A >> i.B >> i.C >> i.D >> i.answer)//信息读取到temp中
{
a.push_back(i);
}
ifs.close();
if (a.empty())
{
cout << "题库为空" << endl;
}
else
cout << "当前题目数目为" << a.size() << "道" << endl;
}
void addTimu(vector<Timu>& a) {
Timu temp;
string s, A, B, C, D, ans;
cout << "请输入题干" << endl;
cin >> temp.tigan;
cout << "请输入A选项" << endl;
cin >> temp.A;
cout << "请输入B选项" << endl;
cin >> temp.B;
cout << "请输入C选项" << endl;
cin >> temp.C;
cout << "请输入D选项" << endl;
cin >> temp.D;
cout << "请输入正确选项" << endl;
cin >> temp.answer;
if (temp.answer >= 'a' && temp.answer <= 'z')temp.answer = temp.answer - 32;
a.push_back(temp);
cout << "添加完成" << endl;
}
void chouTimu(vector<Timu>a, vector<Timu>& b, int N)
{
int x;
for (int i = 0; i < N; ++i) {
x = random(a.size());
b.push_back(a[x]);
a.erase(a.begin() + x);
}
}
int answerTi(vector<Timu>a) {
char c;
int x = 0;
for (int i = 0; i < a.size(); ++i) {
a[i].show();
cout << "请输入你的答案" << endl;
cin >> c;
if (c >= 'a' && c <= 'z')c = c - 32;
if (c == a[i].answer)x++;
}
return 100 * x / a.size();
}
void takeExam(vector<Timu>& a) {
cout << "请输入你想要答题的数目" << endl;
int N;
cin >> N;
if (N > a.size())
{
cout << "当前题目数量不足" << endl;
return;
}
vector<Timu>b;
chouTimu(a, b, N);
int score = answerTi(b);
cout << "你的成绩是" << score << endl;
}
void arrangeTiku(vector<Timu>& a) {
char c;
while (true)
{
showMenu2();
cin >> c;
switch (c) {
case '0'://退出
return;
case '1'://出题
addTimu(a);
break;
case '2'://保存
save(a);
break;
}
system("pause");
system("cls");
}
}
int isUserExist(string name, vector<User>u) {
for (int i = 0; i < u.size(); ++i) {
if (u[i].userName == name) return i;
}
return -1;
}
bool quanxian()
{
cout << "请输入密码来证明您的权限" << endl;
string c;
cin >> c;
return c == "123456";
}
bool denglu(vector<User>& u) {
string name, password;
cout << "请输入用户名" << endl;
cin >> name;
int a = isUserExist(name, u);
if (a == -1) {
cout << "用户名不存在,登录失败" << endl;
return false;
}
else
{
cout << "请输入密码" << endl;
cin >> password;
if (u[a].password == password) {
cout << "登录成功" << endl;
return true;
}
else
{
cout << "密码错误,登录失败" << endl;
return false;
}
}
}
void zhuce(vector<User>& u)
{
string password;
User tmp;
string name;
cout << "请输入用户名" << endl;
cin >> name;
int a = isUserExist(name, u);
if (a == -1)
{
tmp.userName = name;
cout << "请输入密码" << endl;
cin >> password;
tmp.password = password;
u.push_back(tmp);
ofstream ofs;
ofs.open(FILENAME2, ios::out);
for (auto& i : u) {//录入用户信息
ofs << i.userName << " " << i.password << endl;
}
cout << "保存成功" << endl;
ofs.close();//关闭文件
}
else cout << "该用户名已被使用,注册失败" << endl;
}
void fetchUser(vector<User>& u)
{
ifstream ifs;
ifs.open(FILENAME2, ios::in);//读文件
if (!ifs.is_open())//判断是否存在
{
cout << "用户文件不存在" << endl;
ifs.close();
return;
}
User temp;
while (ifs >> temp.userName && ifs >> temp.password)//信息读取到temp中
{
u.push_back(temp);//将temp存在u中
}
ifs.close();
if (u.empty())
{
cout << "用户文件为空" << endl;
}
else
cout << "当前用户数目为" << u.size() << "位" << endl;
}
void select(vector<Timu>& a, vector<User>& b) {
char s, choose0;
int h = 0;
do {
showMenu3();
cin >> choose0;
switch (choose0)
{
case'1'://登录
if (denglu(b))
{
h = 1;
break;
}
else
continue;
case'2'://注册
zhuce(b);
break;
case'0':
cout << "欢迎下次使用" << endl;
return;
}
system("pause");
system("cls");
} while ((choose0 != '0' && h != 1));
while (true)
{
showMenu1();
cin >> s;
switch (s) {
case '0'://退出
cout << "欢迎下次使用" << endl;
return;
case '1'://考试
takeExam(a);
break;
case '2'://整理题库
if (quanxian())
arrangeTiku(a);
else cout << "密码错误,您没有权限" << endl;
break;
default:
cout << "指令错误,请重新输入" << endl;
break;
}
system("pause");
system("cls");
}
}
int main() {
srand(time(0));
vector<Timu> questionBank;
vector<User> userInfo;
fetch(questionBank);
fetchUser(userInfo);
select(questionBank, userInfo);
return 0;
}