zoukankan      html  css  js  c++  java
  • Windows系统对拍程序

    Windows系统对拍程序,其中包含c++11用法,请使用c++11标准编译。此对拍程序会在发现错误时显示错误行号以及对应内容,方便比对。

    此对拍程序自动使用g++对源代码进行编译。如果出现找不到g++的错误,请将g++所在目录添加至系统的环境变量列表中;

    也可直接注释掉主函数前几行不用自动编译,并将编译好的pai_data.exe(生成数据)、pai_user.exe(用户程序)、pai_std.exe(标准解答程序)放至与本程序所在同目录下。

    准备就绪后编译并运行本程序即可。

    UPD 2019-04-10:添加了对标程的计时。

    UPD 2019-04-18:修复当文件尾没有换行时会导致错误判断的问题。

      1 #include <cerrno>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <ctime>
      6 
      7 // 设置区
      8 namespace Settings {
      9 const int MAX_LEN = 20;  // 发现错误时,显示错误行数据的最大长度
     10 const int CASE_CNT = 200;                 // 对拍测试次数
     11 const int BUFFER_SIZE = 1 << 10;          // 每行的缓冲区大小
     12 const char *const dataFile = "data.cpp";  // 随机生成数据的源代码文件名
     13 const char *const userFile = "user.cpp";  // 需要测试的源代码文件名
     14 const char *const stdFile = "std.cpp";    // 标准答案的源代码文件名
     15 const char *const dataExeName = "pai_data.exe";
     16 const char *const userExeName = "pai_user.exe";
     17 const char *const stdExeName = "pai_std.exe";
     18 const char *const dataOutputName = "pai_data.txt";
     19 const char *const userOutputName = "pai_user.txt";
     20 const char *const stdOutputName = "pai_std.txt";
     21 }  // namespace Settings
     22 
     23 using namespace Settings;
     24 using namespace std;
     25 
     26 char cmd[BUFFER_SIZE], info[BUFFER_SIZE * 3];
     27 char buf1[BUFFER_SIZE], buf2[BUFFER_SIZE];
     28 
     29 template <typename... T>
     30 int run(const char *str, T... args) {
     31     sprintf(cmd, str, args...);
     32     return system(cmd);
     33 }
     34 
     35 bool fileCompare(const char *stdOutput, const char *userOutput) {
     36     FILE *fp_std = fopen(stdOutput, "r"), *fp_user = fopen(userOutput, "r");
     37     if (fp_std == nullptr || fp_user == nullptr) {
     38         sprintf(info, "Open file failed: %s
    ", strerror(errno));
     39         return false;
     40     }
     41     bool flag = true;
     42     for (int i = 1; !feof(fp_std) && !feof(fp_user); ++i) {
     43         char *p1 = fgets(buf1, BUFFER_SIZE, fp_std);
     44         char *p2 = fgets(buf2, BUFFER_SIZE, fp_user);
     45         if (p1 == nullptr && p2 == nullptr) {
     46             flag = true;
     47             break;
     48         } else {
     49             int len1 = p1 ? strlen(p1) : -1, len2 = p2 ? strlen(p2) : -1;
     50             if (p1 && p1[len1 - 1] == '
    ') p1[len1 - 1] = 0, --len1;
     51             if (p2 && p2[len2 - 1] == '
    ') p2[len2 - 1] = 0, --len2;
     52             if (p1 == nullptr || p2 == nullptr || len1 != len2 ||
     53                 strcmp(p1, p2)) {
     54                 if (len1 > MAX_LEN)
     55                     sprintf(p1 + MAX_LEN, "... (%d characters omitted)",
     56                             len1 - MAX_LEN);
     57                 if (len2 > MAX_LEN)
     58                     sprintf(p2 + MAX_LEN, "... (%d characters omitted)",
     59                             len2 - MAX_LEN);
     60                 sprintf(info,
     61                         "Difference found in line %d:
      std: %s
     user: %s
    ",
     62                         i, p1 ? p1 : "(EOF Detected)",
     63                         p2 ? p2 : "(EOF Detected)");
     64                 flag = false;
     65                 break;
     66             }
     67         }
     68     }
     69     fclose(fp_std), fclose(fp_user);
     70     return flag;
     71 }
     72 
     73 int main() {
     74     int totaltimeCnt = 0;
     75     printf("Compiling... ");
     76     if (run("g++ %s -o %s", userFile, userExeName) ||
     77         run("g++ %s -o %s", stdFile, stdExeName) ||
     78         run("g++ %s -o %s", dataFile, dataExeName)) {
     79         puts("Compile failed.");
     80         printf("Press ENTER to exit.
    ");
     81         getchar();
     82         return 0;
     83     }
     84 
     85     puts("Finished.");
     86     clock_t stUser, edUser, stStd, edStd;
     87     bool Accepted = true;
     88     for (int i = 1, ret; i <= CASE_CNT; ++i) {
     89         printf("Case %03d: ", i);
     90         run("%s >%s", dataExeName, dataOutputName);
     91 
     92         // run std solution
     93         stStd = clock();
     94         ret = run("%s <%s >%s", stdExeName, dataOutputName, stdOutputName);
     95         edStd = clock();
     96         if (ret) {
     97             printf("Non Zero Exit Code: Std solution returned value %d
    ", ret);
     98             Accepted = false;
     99             break;
    100         }
    101 
    102         // run user's solution
    103         stUser = clock();
    104         ret = run("%s <%s >%s", userExeName, dataOutputName, userOutputName);
    105         edUser = clock();
    106         if (ret) {
    107             printf("Non Zero Exit Code: User's solution returned value %d
    ",
    108                    ret);
    109             Accepted = false;
    110             break;
    111         }
    112 
    113         if (!fileCompare(stdOutputName, userOutputName)) {
    114             printf("Wrong answer.
    ------------------------------
    ");
    115             printf("%s", info);
    116             printf("------------------------------
    ");
    117             Accepted = false;
    118             break;
    119         }
    120 
    121         printf("Accepted. StdTime:%4d ms, UserTime:%4d ms
    ",
    122                int(edStd - stStd), int(edUser - stUser));
    123         totaltimeCnt += int(edUser - stUser);
    124     }
    125     if (Accepted) {
    126         printf("
    User's solution got accepted after %d tests.
    ", CASE_CNT);
    127         printf("Average time spent: %.2f ms.
    ",
    128                double(totaltimeCnt) / CASE_CNT);
    129     }
    130     printf("Press ENTER to exit.
    ");
    131     getchar();
    132     return 0;
    133 }
    View Code
  • 相关阅读:
    程序片段--2的乘方
    Set、Map集合、栈、队列
    Map迭代(六种)
    Struts2标签--控制标签
    线性表
    数据结构笔记(1)
    spingMVC问题小结
    《浪潮之巅》十四章笔记
    《浪潮之巅》十三章笔记
    《浪潮之巅》十二章笔记
  • 原文地址:https://www.cnblogs.com/sandychn/p/10355239.html
Copyright © 2011-2022 走看看