# Trivial Presentation Error Decision for Building Aqours Online Judge

It started in the first semester of sophomore year. There was a course called "Website Construction and Management". Because I am interested in the Web and like the style of Python language, I learned Django while learning PHP taught by my teacher. Just in the first semester of my freshman year, I learned the algorithm. I was interested in the algorithm and all kinds of OJ. So I wrote a manual OJ homework which could not be evaluated and handed it in at the end of the term. This summer vacation began to build this site into a real OJ that can be evaluated. After climbing with Github for a while, I found an open source project like https://github.com/KIDx/Judger, changed the code of this project a lot, and finally I could run. My OJ address is: http://111.230.131.247/JudgeHome./

At present, it is found that the original OJ system judges Presentation Error too strictly, so here we want to change it to the mode of removing the blank space at the end of the line and comparing it with the blank line at the end of the text. The algorithm related to text comparison in the program is extracted and a small program for text comparison is obtained.

``` 1 #include <iostream>
2 using namespace std;
3
4 void compare_until_nonspace(int &c_std, int &c_usr, FILE *&fd_std, FILE *&fd_usr, int &ret)
5 {
6     while((isspace(c_std)) || (isspace(c_usr)))
7     {
8         if (c_std != c_usr)
9         {
10             if (c_std == '\r' && c_usr == '\n')
11             {
12                 c_std = fgetc(fd_std);
13                 if (c_std != c_usr)
14                     ret = 3; //PRESENTATION ERROR
15             }
16             else
17             {
18                 ret = 3; //PRESENTATION ERROR
19             }
20         }
21         if (isspace(c_std))
22             c_std = fgetc(fd_std);
23         if (isspace(c_usr))
24             c_usr = fgetc(fd_usr);
25     }
26 }
27
28 int tt_compare_output(string &file_std, string &file_usr)
29 {
30     int ret = 1; //ACCEPTED
31     int c_std, c_usr;
32     FILE *fd_std = fopen(file_std.c_str(), "r");
33     FILE *fd_usr = fopen(file_usr.c_str(), "r");
34
35     if (fd_std == NULL)
36     {
37         printf("%s open standard file failed %s\n", strerror(errno), file_std.c_str());
38     }
39
40     if (!fd_std || !fd_usr)
41     {
42         ret = -1; //RUNTIME ERROR (ABORTION)
43     }
44     else
45     {
46         c_std = fgetc(fd_std);
47         c_usr = fgetc(fd_usr);
48         for(;;)
49         {
50             compare_until_nonspace(c_std, c_usr, fd_std, fd_usr, ret);
51             while(!isspace(c_std) && !isspace(c_usr))
52             {
53                 //    LOG_DEBUG("std: %c usr: %c", c_std, c_usr);
54                 if (c_std == EOF && c_usr == EOF)
55                     goto end;
56                 if (c_std != c_usr)
57                 {
58                     ret = 2; //WRONG ANSWER
59                     goto end;
60                 }
61                 c_std = fgetc(fd_std);
62                 c_usr = fgetc(fd_usr);
63             }
64         }
65     }
66 end:
67     if (fd_std)
68         fclose(fd_std);
69     if (fd_usr)
70         fclose(fd_usr);
71     return ret;
72 }
73
74 int main() {
75     string file_std = "std.txt";
76     string file_usr = "usr.txt";
77     int res = tt_compare_output(*&file_std, *&file_usr);
78     switch(res) {
79         case -1: cout << "RUNTIME ERROR (ABORTION)" << endl; break;
80         case 1: cout << "ACCEPTED" << endl; break;
81         case 2: cout << "WRONG ANSWER" << endl; break;
82         case 3: cout << "PRESENTATION ERROR" << endl; break;
83         default: cout << "SYSTEM ERROR" << endl;
84     }
85     return 0;
86 }```

Testing the program, we can see that as long as there is any slight difference between usr.txt and std.txt, the program will output PRESENTATION ERROR. With the addition of a simple logic function, it can be realized that the end-of-line blanks and end-of-line blanks in standard output and player output are removed and compared.

```void remove_blank(string file) {
//Delete end-of-text and end-of-line spaces
fstream target_file(file.c_str(), fstream::in | fstream::out);
string line; //As a read line
string temp; //Used as a cache
vector<string> obj; //For storing each row after finishing
if(!target_file) {
cout << "Can't open target file!" << endl; //On-line change to LOG_DEBUG
}
while(getline(target_file, line)) {
unsigned long len = line.length();
int count = 0;
for(unsigned long i=len-1; i>=0; i--) {
int temp_char = line[i]; //Used to convert characters to ASCII Code, save ASCII Code usage
if(isspace(temp_char))
count++;
else break;
}
temp = line.substr(0, len-count);
obj.push_back(temp);
}
int count_lines = 0; //Number of blank lines at the end of the article
for(unsigned long i=obj.size()-1; i>=0; i--) {
//Remove empty lines at the end of the article
if(obj[i].empty())
count_lines++;
else break;
}
cout << "count_lines: " << count_lines << endl;
for(int i=0; i<count_lines; i++)
obj.pop_back();
//Use ofstream Open and close files to empty source files
ofstream empty_file(file.c_str());
empty_file.close();
//Reopen the text file
fstream target(file.c_str(), fstream::out | fstream::in);
if(!target) {
cerr << "Can't open file" << endl; //On-line change to LOG_DEBUG
}
//Write back to the source file
for(unsigned long i=0; i<obj.size(); i++)
target << obj[i] << endl;
target.close();
}```

It should be noted that in the g++ compiler of Linux, the parameters of fstream, ofstream and so on need to be C-type strings, and the common string type needs to be converted to C-type strings through c_str to be compiled. The clang compiler under mac that I use does not have this requirement. It can also be compiled by using string type directly. Deug has been here for a long time. Be careful.

Posted on Wed, 24 Jul 2019 21:45:54 -0700 by AliasZero