离线OJ程序:离线在线判题系统

引言

在互联网时代,在线判题系统成为了程序员学习和练习编程的必备工具。然而,有时候我们可能会遇到无法连接互联网的情况,这就无法使用在线判题系统了。那有没有一种能够在离线环境下进行编程练习和判题的方法呢?答案是有的!今天我来介绍一个离线的在线判题系统 - 离线OJ。

使用方法

离线OJ是一个基于C++开发的离线在线判题系统。它可以让你在没有互联网连接的情况下,通过编写代码并提交进行判题。下面我来逐步介绍一下离线OJ的使用方法。

  1. 运行离线OJ程序 首先,你需要将离线OJ的代码拷贝到你的本地计算机上,并且配置好C++编译环境。然后,通过命令行或集成开发环境(IDE)运行程序。

  2. 查看题目 运行离线OJ程序后,它会显示一个菜单选项,你可以通过输入相应的数字选择要执行的操作。选择1可以查看题目列表,程序会将当前的题目列表显示在屏幕上。

  3. 添加题目 如果你想要添加新的题目,选择菜单中的选项2。然后按照程序的提示,依次输入题目名称、描述、样例输入、样例输出、输入数据和期望输出。题目会被添加到题目列表中。

  4. 提交代码进行判题 现在你可以选择查看题目或退出程序。如果选择查看题目,程序会要求你输入要查看的题目编号。然后它会显示该题目的详细信息,并询问你选择提交方式。你可以选择输入代码文件名或直接输入代码。

    • 如果选择输入文件名,则需要将你的C++代码保存在一个文件中,并输入该文件的文件名。程序会读取文件中的代码进行编译和运行。
    • 如果选择直接输入代码,则可以在终端中直接输入C++代码。输入两个#符号可以结束代码输入。

    无论选择哪种提交方式,程序都会将你的代码与题目的输入进行编译运行,并将运行结果与题目的期望输出进行比较,给出判题结果。

  5. 退出程序 当你完成了编程练习,或者想要结束判题过程时,可以选择退出程序。程序会统计你已通过的题目数量,并显示在屏幕上。

离线OJ作为一个离线的在线判题系统,给你提供了一种在离线环境下进行编码和练习的方式。不论你是在火车上、飞机上,还是在没有互联网连接的地方,都可以通过离线OJ来提升你的编程技巧。

源码展示

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <windows.h>

using namespace std;

struct Problem {
    string title;
    string description;
    string sampleInput;
    string sampleOutput;
    string input;
    string expectedOutput;
    bool isPassed; // 新增标志,表示该问题是否已被通过
};

vector<Problem> problems = {
    {"题目1: 两个数的和", "计算两个整数的和。", "3 5", "8", "3 5", "8", false},
    {"题目2: 两个数的乘积", "计算两个整数的乘积。", "4 6", "24", "4 6", "24", false},
    {"题目3: 两个数的差", "计算两个整数的差。", "10 4", "6", "10 4", "6", false}
};

void compileAndRun(const string& code, const string& input, string& output) {
    string filename = "temp.cpp";
    ofstream codeFile(filename);
    codeFile << code;
    codeFile.close();

    string compileCommand = "g++ " + filename + " -o temp.exe 2> compile_error.txt";
    system(compileCommand.c_str());

    string runCommand = "temp.exe < input.txt > output.txt";

    ofstream inputFile("input.txt");
    inputFile << input;
    inputFile.close();

    system(runCommand.c_str());

    ifstream outputFile("output.txt");
    getline(outputFile, output);
    outputFile.close();

    remove("input.txt");
    remove("temp.exe");
    remove("output.txt");
    remove("compile_error.txt");
    remove(filename.c_str());
}

void addProblem() {
    Problem newProblem;
    cout << "请输入题目名称: ";
    getline(cin, newProblem.title);
    cout << "请输入题目描述: ";
    getline(cin, newProblem.description);
    cout << "请输入样例输入: ";
    getline(cin, newProblem.sampleInput);
    cout << "请输入样例输出: ";
    getline(cin, newProblem.sampleOutput);
    cout << "请输入输入数据: ";
    getline(cin, newProblem.input);
    cout << "请输入期望输出: ";
    getline(cin, newProblem.expectedOutput);
    newProblem.isPassed = false; // 初始化为未通过
    problems.push_back(newProblem);
    cout << "题目添加成功!\n";
}

void viewProblems() {
    cout << "当前题目列表:\n";
    for (size_t i = 0; i < problems.size(); ++i) {
        cout << i + 1 << ". " << problems[i].title << "\n";
    }
}

void viewProblemDetails(int index) {
    if (index < 1 || index > problems.size()) {
        cout << "无效的题目索引!\n";
        return;
    }

    Problem& problem = problems[index - 1];
    cout << "题目名称: " << problem.title << "\n";
    cout << "题目描述: " << problem.description << "\n";
    cout << "样例输入: " << problem.sampleInput << "\n";
    cout << "样例输出: " << problem.sampleOutput << "\n";

    cout << "请选择提交方式 (1. 输入文件名 2. 直接输入代码): ";
    int submitChoice;
    cin >> submitChoice;
    cin.ignore();

    string code;
    if (submitChoice == 1) {
        cout << "请输入你的C++代码文件名: ";
        string filename;
        getline(cin, filename);
        ifstream codeFile(filename);
        if (codeFile) {
            getline(codeFile, code, '\0');
            codeFile.close();
        } else {
            cout << "文件读取失败!\n";
            return;
        }
    } else if (submitChoice == 2) {
        cout << "请输入你的C++代码 (输入两个#停止输入):\n";
        string line;
        while (getline(cin, line) && line != "##") {
            code += line + "\n";
        }
    } else {
        cout << "无效的选择!\n";
        return;
    }

    string output;
    compileAndRun(code, problem.input, output);

    if (output == problem.expectedOutput) {
        cout << "答案正确!\n";
        if (!problem.isPassed) { // 只有在未通过的情况下才增加计数
            problem.isPassed = true; // 标记为已通过
        }
    } else {
        cout << "答案错误!\n";
    }
    system("pause");
}

void clearScreen() {
    system("cls");
}

int main() {
    int passedCount = 0;

    while (true) {
        clearScreen();
        cout << "欢迎来到离线OJ\n";
        cout << "1. 查看题目\n";
        cout << "2. 添加题目\n";
        cout << "3. 退出\n";
        cout << "请输入你的选择: ";

        int choice;
        cin >> choice;
        cin.ignore();

        if (choice == 1) {
            viewProblems();
            cout << "请输入要查看的题目编号: ";
            int problemIndex;
            cin >> problemIndex;
            cin.ignore();
            viewProblemDetails(problemIndex);
        } else if (choice == 2) {
            addProblem();
            system("pause");
        } else if (choice == 3) {
            for (const auto& problem : problems) {
                if (problem.isPassed) {
                    passedCount++;
                }
            }
            cout << "你已通过 " << passedCount << " 道题目。\n";
            break;
        } else {
            cout << "无效的选择!\n";
            system("pause");
        }
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值