Testlib 是用於實現 SpecialJudge 的一種方式
為了使用 Testlib,你需要在你的檔案中引用 Testlib.h
testlib.h 下載
使用 Testlib 程式
以 Testlib 的 check 功能示例(實際上 Tesklib 不止可以實現 check 功能)
首先你需要正確的引用到 testlib.h,一般有以下兩種方式
- 直接丟到編譯器的
MinGW/include
目錄下 - 直接丟到原始碼目錄下(需要用雙引號引用)
或者你也可以直接寫具體路徑,比如 #include "C:/Desktop/testlib.h"
之類的
或者使用相對路徑
相對路徑就是基於當前資料夾向前或向後翻的一種路徑,比如對於如下目錄結構:
-Desktop
-Folder1
-Folder2
-file.cpp
-Folder3
-Folder4
-testlib.h
假若你想要在 file.cpp
中引用到 testlib.h
,你也可以這麼寫:
#include"../../Folder1/Folder2/testlib.h"
其中 ../
表示返回上級目錄
在將下發的 checker.cpp 程式編譯完成後,就可以按照如下格式進行 checker
(一般來說是在終端中進行編譯執行,進行之前請先跳到 checker 所在目錄,並請將其他檔案也放進去)
Windows checker.exe input output answer
Linux ./checker input output answer
input
題目的輸入檔案,這個檔案也可以用資料生成器跑出來
output
你的程式的輸出檔案
answer
答案檔案 一般情況下,你寫對拍的時候是拿不到這個答案檔案的,但是你仍然可以檢驗一部分正確性:比如透過模擬能判斷出來的部分,或者是格式檢驗的部分。這就需要考驗你對 checker
進行改寫的能力了。一般在這種情況下,你完全可以在 answer
位置傳一個無關緊要的檔案,或者直接把 output
傳進去,但是不能空著
在使用 checker 跑對拍的時候,你可能需要判斷什麼時候應該 pause,事實上是這樣判斷的:
在呼叫 cmd 或 Linux 終端的時候,system() 函式實際上是有返回值的,它返回的是程式主程式的 return 值。而 testlib.h 會在正確時返回 0,出現錯誤時返回 1,因此你可以透過這一點來判斷正確性,即這麼寫:
if(system("checker.exe input output answer")){
system("pause");
}
編寫 Testlib 程式
顯然,你不應該使用標準輸入輸出函式(互動題等特殊題型除外),而應該使用 testlib 提供的讀入函式
你需要在主函式使用入下內容以初始化 testlib
int main(int argc, char* argv[]) {
registerTestlibCmd(argc, argv);
}
此外,testlib 不支援使用 <random> 下的大部分內容,如果你真的要用 rand()
,testlib 提供了兩種方法:
- 使用 mt19937
- 使用內建函式
關於內建函式
* Use "shuffle", and "rnd.next()" instead of them
* because these calls produce stable result for any C++ compiler. Read
* sample generator sources for clarification.
*
* Please read the documentation for class "random_t" and use "rnd" instance in
* generators. Probably, these sample calls will be useful for you:
* rnd.next(); rnd.next(100); rnd.next(1, 2);
* rnd.next(3.14); rnd.next("[a-z]{1,100}").
關於檔案讀入,上述傳入的三個檔案,分別對應了三個 ifstream
型別的類,分別命名為:
inf
對應 input
ouf
對應 output
ans
對應 answer
它們的讀入函式如下所示:
函式 | 功能 |
---|---|
char readChar() | 讀入一個 char |
char readChar(char c) | 限定讀入字元,不符合則判為 _wa |
char readSpace() | 讀入一個空格 |
string readToken() | 讀入一個字串,遇到空格、換行、eof 為止、 |
long long readLong() | 讀入一個 longlong |
long long readLong(long long L, long long R) | 限定讀入範圍(包括 L,R),超出則判為 _wa |
int readInt() | 讀入一個 int |
int readInt(int L, int R), | 限定讀入範圍(包括 L,R),超出則判為 _wa |
double readReal() | 讀入一個實數 |
double readReal(double L, double R), | 限定讀入範圍(包括 L,R),超出則判為 _wa |
double readStrictReal(double L, double R, int minPrecision, int maxPrecision), | 限定精度範圍(包括 L,R),超出則判為 _wa |
string readString() | 讀入一個字串 |
string readLine() | 讀入一行 string,到換行或者 eof 為止 |
void readEoln() | 讀入一個換行符 |
void readEof() | 讀入一個 eof |
int eof() | 已到達檔案末尾則返回 1 |
關於判定,使用以下三個函式
quitf(st,...)
第一個引數用來傳入引數,告訴程式該答案正確還是不正確,有兩種,一種為 _ac
,一種為 _wa
,後面主要是用於輸出判斷資訊,會顯示出來給人看,用法和格式化輸出一致,如 quitf(_wa,"Answer is wrong, except %d, but read %d",ans,p);
quitp(score,..)
用來判 “部分正確”,第一個引數用來傳入一個 \([0,1]\) 的實數,表示得分百分比,後面就一樣了
testlib 程式會在讀入格式錯誤,或者檔案未被讀完的時候報出 wrong output format
錯誤,為了避免這個錯誤,你也可以使用 while(!ouf.seekEof()) ouf.readToken()
來讀完剩下的內容