----------------------------------------------------- 2019/07/14 -----------------------------------------------------

添加自我上传题目功能,输入表达等式即可.

修复若干 Bug

----------------------------------------------------- 2019/07/13 -----------------------------------------------------

用户登录、注册功能.

我要刷题

错题重刷

刷题记录

AC 过的题

WA 过的题

管理员特用功能(第一名注册者默认管理员)

{

删除账号

取消管理员

设置管理员

}

只需修改开头宏定义 Root 路径即可.  

#include <io.h>
#include <ctime>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <windows.h>
#include <bits/stdc++.h>
#define eps 1e-2
#define Root "这里填地址\\User\\"
using namespace std;

struct User
{
    char id[10], password[20];
    bool flag;
};

struct Equation
{
    double num1, num2;
    char sym[3];
    double ans;
};

struct date
{
    int num;
    int year, month, day;
    int hour, minute, second;
};

char User_txt[100];
char Assist_txt[100];
char Wronged_txt[100];
char Id_Road_txt[100];
char Accepted_txt[100];
char Recorder_txt[100];
char Attempted_txt[100];

void Compose(char tmp[], char s1[], char s2[])
{
    strcpy(tmp, s1);
    strcat(tmp, s2);
}

void User_inf_init(char id[])
{
    char tmp[100];
    Compose(tmp, id, "\\");
    Compose(Id_Road_txt, Root, tmp);
    Compose(Assist_txt, Id_Road_txt, "Assist.txt");
    Compose(Wronged_txt, Id_Road_txt, "Wronged.txt");
    Compose(Accepted_txt, Id_Road_txt, "Accepted.txt");
    Compose(Recorder_txt, Id_Road_txt, "Recorder.txt");
    Compose(Attempted_txt, Id_Road_txt, "Attempted.txt");
}

void Save(char name[], struct Equation equ)
{
    FILE *fp;
    fp = fopen(name, "ab");
    fwrite(&equ, sizeof(equ), 1, fp);
    fclose(fp);
}

void Print_Equ(struct Equation equ)
{
    printf("%.2f %s %.2f = ", equ.num1, equ.sym, equ.num2);
}

bool Check(struct Equation equ, int &Total, int &Accpted)
{
    Print_Equ(equ);
    double ans;
    scanf("%lf", &ans);
    Total++;
    if(fabs(ans - equ.ans) < 2.0 * eps)
    {
        Accpted++;
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY |FOREGROUND_GREEN);
        printf("Yes\n");
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN);
        return 1;
    }
    else
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY |FOREGROUND_RED);
        printf("No\n");
        printf("正确答案:%f\n", equ.ans);
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN);
        return 0;
    }
}

Equation Create_Equ(int Max)
{
    struct Equation equ;
    equ.num1 = fmod(int(rand() * 2.71828 * 100.0) / 100.0, Max);
    equ.num2 = fmod(int(rand() * 2.71828 * 100.0) / 100.0, Max);
    if(equ.num1 < equ.num2)
        swap(equ.num1, equ.num2);
    int sym = rand() % 4;
    switch(sym)
    {
    case 0:
        strcpy(equ.sym, "+"), equ.ans = equ.num1 + equ.num2;
        break;
    case 1:
        strcpy(equ.sym, "-"), equ.ans = equ.num1 - equ.num2;
        break;
    case 2:
        strcpy(equ.sym, "×"), equ.ans = equ.num1 * equ.num2;
        break;
    case 3:
        strcpy(equ.sym, "÷"), equ.ans = equ.num1 / equ.num2;
        break;
    }
    equ.ans = (int)(equ.ans * 100) / 100.0;
    return equ;
}

int First_Test()
{
    int Max;
    printf("请输入最大值:");
    scanf("%d", &Max);
    char ch;
    int Total = 0;
    int Accepted = 0;
    while((ch = getchar()) != 'E')
    {
        system("cls");
        struct Equation equ = Create_Equ(Max);
        if(!Check(equ, Total, Accepted))
        {
            Save(Attempted_txt, equ);
            Save(Wronged_txt, equ);
        }
        else
            Save(Accepted_txt, equ);
        getchar();
    }
    printf("\n总题数:%d\n正确数:%d\n正确率:%.2f%\n", Total, Accepted, 100.0 * Accepted / Total);
    return Accepted;
}

int Second_Test()
{
    int Total = 0;
    int Accepted = 0;
    struct Equation equ;
    FILE *fp1 = fopen(Attempted_txt, "rb");
    FILE *fp2 = fopen(Assist_txt, "wb");
    FILE *fp3 = fopen(Accepted_txt, "ab");
    char ch;
    while(!feof(fp1) && (ch = getchar()) != 'E')
    {
        system("cls");
        fread(&equ, sizeof(equ), 1, fp1);
        if(!feof(fp1))
        {
            if(!Check(equ, Total, Accepted))
                fwrite(&equ, sizeof(equ), 1, fp2);
            else
                fwrite(&equ, sizeof(equ), 1, fp3);
            getchar();
        }
    }
    while(!feof(fp1))
    {
        fread(&equ, sizeof(equ), 1, fp1);
        if(!feof(fp1))
            fwrite(&equ, sizeof(equ), 1, fp2);
    }
    fclose(fp1);
    fclose(fp2);
    fclose(fp3);
    remove(Attempted_txt);
    rename(Assist_txt, Attempted_txt);
    printf("\n总题数:%d\n正确数:%d\n正确率:%.2f%\n", Total, Accepted, 100.0 * Accepted / Total);
    getchar();
    return Accepted;
}

int Lasted_Recorder(bool flag)
{
    struct date t;
    FILE *fp = fopen(Recorder_txt, "rb");
    if(flag)
        printf("刷题数\t\t日期\n\n");
    while(!feof(fp))
    {
        fread(&t, sizeof(t), 1, fp);
        if(!feof(fp) && flag)
        {
            printf("  %d\t%d/", t.num, t.year);
            if((int)(log10(t.month) + 1) != 2)
                printf("0");
            printf("%d/", t.month);
            if((int)(log10(t.day) + 1) != 2)
                printf("0");
            printf("%d ", t.day);
            if((int)(log10(t.hour) + 1) != 2)
                printf("0");
            printf("%d:", t.hour);
            if((int)(log10(t.minute) + 1) != 2)
                printf("0");
            printf("%d:", t.minute);
            if((int)(log10(t.second) + 1) != 2)
                printf("0");
            printf("%d\n", t.second);
        }
    }
    fclose(fp);
    if(flag)
        getchar(), getchar();
    system("cls");
    return t.num;
}

void Update_Recorder(int num, bool flag)
{
    time_t timep;
    struct tm *p;
    time (&timep);
    p = gmtime(&timep);
    struct date t;
    t.year = 1900 + p->tm_year;
    t.month = 1 + p->tm_mon;
    t.day = p->tm_mday;
    t.hour = 8 + p->tm_hour;
    t.minute = p->tm_min;
    t.second = p->tm_sec;
    FILE *fp = fopen(Recorder_txt, "ab");
    t.num = flag ? num + Lasted_Recorder(0) : 0;
    fwrite(&t, sizeof(t), 1, fp);
    fclose(fp);
}

Equation Equ_input()
{
    struct Equation equ;
    char s[100];
    scanf("%s", s);
    int len = strlen(s);
    int integer, decimal;
    integer = decimal = 0;
    bool dot = 0;
    int flag = 0;
    for(int i = 0; i < len; ++i)
    {
        if(!isdigit(s[i]) && s[i] != '.' && s[i] != '=')
        {
            switch(s[i])
            {
            case '+':
                strcpy(equ.sym, "+");
                break;
            case '-':
                strcpy(equ.sym, "-");
                break;
            case '*':
                strcpy(equ.sym, "×");
                break;
            case '/':
                strcpy(equ.sym, "÷");
                break;
            }
            s[i] = ' ';
        }
        else if(s[i] == '=')
            s[i] = ' ';
    }
    int pos = 0;
    stringstream ss;
    ss << s;
    double num;
    while(ss >> num)
    {
        switch(pos)
        {
        case 0:
            equ.num1 = num;
            break;
        case 1:
            equ.num2 = num;
            break;
        case 2:
            equ.ans = num;
            break;
        }
        pos++;
    }
    return equ;
}

int Third_Test()
{
    char ch;
    int Total, Accepted;
    Total = Accepted = 0;
    while((ch = getchar()) != 'E')
    {
        system("cls");
        printf("自我检测\n\n");
        struct Equation equ = Equ_input();
        double ans;
        if(!strcmp(equ.sym, "+"))
            ans = equ.num1 + equ.num2;
        else if(!strcmp(equ.sym, "-"))
            ans = equ.num1 - equ.num2;
        else if(!strcmp(equ.sym, "×"))
            ans = equ.num1 * equ.num2;
        else if(!strcmp(equ.sym, "÷"))
            ans = equ.num1 / equ.num2;
        swap(ans, equ.ans);
        if(fabs(ans - equ.ans) < 2.0 * eps)
        {
            Accepted++;
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY |FOREGROUND_GREEN);
            printf("Yes\n");
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN);
            Save(Accepted_txt, equ);

        }
        else
        {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY |FOREGROUND_RED);
            printf("No\n");
            printf("正确答案:%f\n", equ.ans);
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN);
            Save(Attempted_txt, equ);
            Save(Wronged_txt, equ);
        }
        getchar();
    }
    Update_Recorder(Accepted, 1);
}

bool Print_User_Windows(char id[], bool flag)
{
    system("cls");
    printf("[%s]\n\n", id);
    printf("1.我要刷题\n");
    printf("2.错题重刷\n");
    printf("3.自我检测\n");
    printf("4.刷题记录\n");
    printf("5.Accepted\n");
    printf("6.Wrong Answer\n");
    printf("7.注销账号\n");
    if(flag)
    {
        printf("8.删除账号\n");
        printf("9.取消管理员\n");
        printf("10.设置管理员\n");
    }
    return 1;
}

void Show(char name[])
{
    if(!strcmp(name, Accepted_txt))
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY |FOREGROUND_GREEN);
    else if(!strcmp(name, Wronged_txt))
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY |FOREGROUND_RED);
    FILE *fp = fopen(name, "rb");
    int cnt = 1;
    struct Equation equ;
    while(!feof(fp))
    {
        fread(&equ, sizeof(equ), 1, fp);
        if(!feof(fp))
            printf("%d. %.2f %s %.2f = %.2f\n", cnt++, equ.num1, equ.sym, equ.num2, equ.ans);
    }
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
    getchar();
    getchar();
}

void Delete_User()
{
    FILE *fp1 = fopen(User_txt, "rb");
    struct User user;
    while(!feof(fp1))
    {
        fread(&user, sizeof(user), 1, fp1);
        if(!feof(fp1))
            printf("%s\t%s\t%s\n", user.id, user.password, user.flag ? "管理员" : "非管理员");
    }
    fclose(fp1);
    char User_Assist_txt[100];
    Compose(User_Assist_txt, Root, "User_Assist.txt");
    fp1 = fopen(User_txt, "rb");
    FILE *fp2 = fopen(User_Assist_txt, "wb");
    printf("请输入删除 ID:");
    char D_id[100];
    scanf("%s", D_id);
    while(!feof(fp1))
    {
        fread(&user, sizeof(user), 1, fp1);
        if(!feof(fp1) && strcmp(D_id, user.id))
            fwrite(&user, sizeof(user), 1, fp2);
    }
    fclose(fp1);
    fclose(fp2);
    remove(User_txt);
    rename(User_Assist_txt, User_txt);
    User_inf_init(D_id);
    remove(Accepted_txt);
    remove(Wronged_txt);
    remove(Attempted_txt);
    remove(Recorder_txt);
    Compose(User_Assist_txt, Root, D_id);
    rmdir(User_Assist_txt);
}

void Update_Adm(bool flag)
{
    FILE *fp1 = fopen(User_txt, "rb");
    struct User user;
    while(!feof(fp1))
    {
        fread(&user, sizeof(user), 1, fp1);
        if(!feof(fp1))
            printf("%s\t%s\t%s\n", user.id, user.password, user.flag ? "管理员" : "非管理员");
    }
    fclose(fp1);
    printf("请输入所%s管理员的Id:", flag ? "设置" : "取消");
    char Id[100];
    scanf("%s", Id);
    char User_Assist_txt[100];
    Compose(User_Assist_txt, Root, "User_Assist.txt");
    fp1 = fopen(User_txt, "rb");
    FILE *fp2 = fopen(User_Assist_txt, "wb");
    while(!feof(fp1))
    {
        fread(&user, sizeof(user), 1, fp1);
        if(!feof(fp1))
        {
            if(!strcmp(Id, user.id))
                user.flag = flag;
            fwrite(&user, sizeof(user), 1, fp2);
        }
    }
    fclose(fp1);
    fclose(fp2);
    remove(User_txt);
    rename(User_Assist_txt, User_txt);
}

void User_Windows(char id[], bool flag)
{
    User_inf_init(id);
    while(Print_User_Windows(id, flag))
    {
        int dir;
        scanf("%d", &dir);
        if(dir == 1)
            Update_Recorder(First_Test(), 1);
        else if(dir == 2)
            Update_Recorder(Second_Test(), 1);
        else if(dir == 3)
            Update_Recorder(Third_Test(), 1);
        else if(dir == 4)
            Lasted_Recorder(1);
        else if(dir == 5)
            Show(Accepted_txt);
        else if(dir == 6)
            Show(Wronged_txt);
        else if(dir == 7)
            return;
        else if(flag)
        {
            if(dir == 8)
            {
                Delete_User();
                User_inf_init(id);
            }
            else if(dir == 9)
                Update_Adm(0);
            else if(dir == 10)
                Update_Adm(1);
        }
        else
        {
            printf("输入非法\n");
            getchar();
            getchar();
        }
    }
}

void Login()
{
    system("cls");
    char id[10];
    char pw[10];
    printf("请输入账号:");
    scanf("%s", id);
    printf("请输入密码:");
    scanf("%s", pw);
    FILE *fp = fopen(User_txt, "rb");
    int flag = 0;
    struct User tmp;
    while(!feof(fp))
    {
        fread(&tmp, sizeof(tmp), 1, fp);
        if(!feof(fp) && !strcmp(tmp.id, id))
        {
            if(!strcmp(tmp.password, pw))
                flag = 1;
            else
                flag = 2;
            break;
        }
    }
    fclose(fp);
    switch(flag)
    {
    case 0:
        printf("\n账号不存在\n"), getchar(), getchar();
        break;
    case 1:
        User_Windows(tmp.id, tmp.flag);
        break;
    case 2:
        printf("\n密码错误\n"), getchar(), getchar();
        break;
    }
}

void Create_User_inf(char name[])
{
    FILE *fp = fopen(name, "wb");
    fclose(fp);
}

void Create_User(struct User tmp)
{
    User_inf_init(tmp.id);
    if(!tmp.flag)
        tmp.flag = 0;
    FILE *fp = fopen(User_txt, "ab");
    fwrite(&tmp, sizeof(tmp), 1, fp);
    fclose(fp);
    _mkdir(Id_Road_txt);
    Create_User_inf(Accepted_txt);
    Create_User_inf(Wronged_txt);
    Create_User_inf(Attempted_txt);
    Create_User_inf(Recorder_txt);
    Update_Recorder(0, 0);
}

void Register()
{
    system("cls");
    User tmp;
    char id[10], pw[20];
    printf("请输入用户名:");
    scanf("%s", id);
    printf("请输入密码:");
    scanf("%s", pw);
    bool tmp_flag;
    if(access(Root, 0))
    {
        _mkdir(Root);
        tmp_flag = 1;
    }
    else
        tmp_flag = 0;
    FILE *fp = fopen(User_txt, "rb");
    if(!fp)
    {
        fclose(fp);
        fp = fopen(User_txt, "wb");
        fclose(fp);
        fp = fopen(User_txt, "rb");
    }
    bool flag = 0;
    while(!feof(fp))
    {
        fread(&tmp, sizeof(tmp), 1, fp);
        if(!feof(fp))
        {
            if(!strcmp(tmp.id, id))
            {
                flag = 1;
                break;
            }
        }
    }
    fclose(fp);
    if(flag)
    {
        printf("该用户名已注册\n");
        getchar();
        getchar();
    }
    else
    {
        strcpy(tmp.id, id);
        strcpy(tmp.password, pw);
        tmp.flag = tmp_flag;
        Create_User(tmp);
    }
}

bool Main_Windows()
{
    printf("1.登录\n");
    printf("2.注册\n");
    printf("3.退出\n");
    return 1;
}

void Main()
{
    Compose(User_txt, Root, "User.txt");
    while(Main_Windows())
    {
        int dir;
        scanf("%d", &dir);
        if(dir == 1)
            Login();
        else if(dir == 2)
            Register();
        else if(dir == 3)
            exit(0);
        else
        {
            printf("输入非法\n");
            getchar();
            getchar();
        }
        system("cls");
    }
}

int main()
{
    srand(time(NULL));
    Main();
    return 0;
}