#include "system.cpp"
#include "test.cpp"
#include "knowledge.cpp"
#include "judge.cpp"
#define MAX_LINE 1024
using namespace std;
int main()
{ judge judge;
test test;
knowledge knowledge;
system("open .");//mac不方便打开关联文件存储路径,故使用system
if(judge.judge1()==0)judge.judge2();
if(judge.judge1()==1){
while(true){
loop: printf("欢迎使用本系统:\n1.完形填空考试\n");
printf("2.错题归纳\n");
printf("3.管理员登陆\n");
printf("请输入您要选择的操作:");
int l = 0;
scanf("%d", &l);
switch(l){
case 1:{
//完形填空
system("cls");
knowledge.out();
test.out();
break;
}
case 2:{
//错题归纳
system("cls");
test.wrongtest();
break;
}
case 3:{
//管理员操作
system("cls");
printf("请输入管理员密码:\n");
if(judge.judge3()==1){
printf("密码正确,请选择操作:\n");
while (true) {
printf("1.修改管理员密码\n");
printf("2.修改数据文件\n");
printf("3.返回上一级\n");
printf("请输入您要选择的操作:");
int i=0;
cin>>i;
switch(i){
case 1:{
system("cls");
judge.judge4();
break;
}
case 2:{
system("cls");
system("open .");
break;
}
case 3:{
goto loop;
break;
}
}
}
}
else {printf("密码错误,程序退出!");
return 0;}
}
break;
}
}}
return 0;
}
⬆️main函数
#include "system.cpp"
using namespace std;
class test{
public:
char a[100][MAX_SIZE];
char b[100];
char c[100][MAX_SIZE];
char buf[MAX_SIZE];
void out(){
int i=0;
int j=0;
int k=0;
char x;
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
FILE *fp,*p;
if ((fp = fopen("test.txt", "r")) == NULL)//判断如果为空则不存在该文件
{
perror("fail to read");
return;
}
if ((p = fopen("answer.txt", "r")) == NULL)//判断如果为空则不存在该文件
{
perror("fail to read");
return;
}
fgets(buf, MAX_SIZE, p);
strcpy(b, buf);
while(fgets(buf,MAX_SIZE,fp)!=NULL)
{
strcpy(a[i], buf);
cout<<a[i];
fflush(stdin);//清空缓冲区!!!!!!!!!!
scanf("%c",&x);
if(x==b[i])j++;
else
{
strcpy(c[k], buf);
k++;
}
i++;
}
cout<<"您的得分是:"<<j<<endl;
fclose(fp);
fclose(p);
}
void wrongtest(){
int i=0;
for(;i<16;i++){
cout<<c[i]<<endl;
}
}
};
⬆️test.cpp:用于出题及计分。
#include "system.cpp"
using namespace std;
class knowledge{
public:
char buf[MAX_SIZE];
void out()
{
FILE *fp;
if((fp=fopen("knowledge.txt", "r"))==NULL)
{
perror("fail to read");
return;
}
while (fgets(buf, MAX_SIZE, fp)) {
cout<<buf<<endl;
}
fclose(fp);
}
};
⬆️knowleg.cpp:用于把txt文件内容输出。
#include "system.cpp"
using namespace std;
class judge{
public:
FILE *fp,*p;
char buf[MAX_SIZE];
char bui[MAX_SIZE];
long len;
int judge1()
//判断是否是第一次运行系统
{
fp=fopen("judge.txt","r");
fgets(buf,MAX_SIZE,fp);
len=strlen(buf);
if(buf[len-1]=='0'){
fclose(fp);
return 0;
}
fclose(fp);
return 1;
}
void judge2()
//第一次设置密码
{
fstream f1,f2;
f1.open("psw.txt",ios::in|ios::out|ios::trunc);
f2.open("judge.txt",ios::in|ios::out);
printf("%s","检测到您初次使用本系统,请设置管理员密码:\n");
cin>>bui;
f1<<bui;
f2<<1;
f1.close();
f2.close();
}
int judge3()
//判断密码是否正确
{
fstream f1;
f1.open("psw.txt",ios::in|ios::out);
char psw[1024],psw1[1024];
memset(psw, 0, sizeof(psw));
memset(psw1, 0, sizeof(psw1));
f1>>psw;
f1.close();
cin>>psw1;
if(strcmp(psw,psw1)==0)return 1;
else return 0;
}
void judge4()
//重置密码
{
char psw1[MAX_SIZE];
memset(psw1, 0, sizeof(psw1));
fstream f1;
f1.open("psw.txt",ios::in|ios::out|ios::trunc);
char psw2[MAX_SIZE]={'1','2','3','4','5'};
f1<<psw2;
f1.close();
cout<<"密码已重置为12345,请输入新的管理员密码"<<endl;
f1.open("psw.txt",ios::in|ios::out|ios::trunc);
cin>>psw1;
f1<<psw1;
f1.close();
}
};
⬆️judge.cpp:用于对系统的体系构建(?)。
#include<string>
#include<fstream>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 1024
using namespace std;
⬆️system.cpp:引用了一些头文件。
本来想加一个登录系统以及学生成绩记录管理系统,但是期末时间不够了,有时间再加上。这些功能本质上都是对fstream类和文件函数的调用,和程序内test等类所使用方法大同小异。
学生成绩记录txt文件可用fstream进行,因为fgets()是按行读取,为了存储的方便,可用>>和<<进行读写文件操作。
未解决问题:代码用xcode写的,在xcode运行的时候会有中文及中文字符无法输出(输出由斜杠数字组成的乱码)的情况,不知道是通病还是编译的问题。其次没找到在mac上可以使用的清屏代码(clear和cls都无效)。交互界面比较杂乱。
进阶想法:这次代码中的问题和答案都是从文本文件中获取然后分别存入两个字符数组中。其中问题存入二维字符数组,行数代表题号,一行一问。而因为答案都是单个英文字符,故用字符串存储,然后通过数组下标去调用,较为方便。后来写完一想,其实可以用表来存储,顺序表或者链表都可以。或许会使代码变得更简洁。还需熟悉表的基本操作以及迭代器的使用方法。
特殊问题:while循环中进行键盘输入操作时,需在scanf()或cin>>前一行加一行fflush(stdin)用于清空缓冲区,否则就会出现一次读出两行的情况。
以上是写完代码后的一点想法,希望前辈们指点!