用C實現一個簡單的對拍器——致每一個曾經爲求AC披星戴月的程序員們

大一新生,首次創做,虛心受教。linux

實現思路:編程

1、須要一個輸入文件(input.txt),兩個對拍程序(main1.exe,main2.exe)windows

2、將標準輸入重定向爲input.txt。將標準輸出分別重定向爲output1.txt,output2.txt。函數

3、對兩個輸出文件進行比較,輸出結果。學習

具體實現:網站

1、所需頭文件this

 1:  #include <stdio.h>
 2:  #include <stdlib.h>
 3:  #include <sys/file.h>       
 4:  #include <unistd.h>
 5:  #include <sys/types.h>

 

2、文件重定向並進行系統調用執行main1.exe main2.txtspa

 1:      int fdout1 = open("stdout1.txt", O_RDWR|O_TRUNC|O_CREAT, 0);
 2:      int fdout2 = open("stdout2.txt", O_RDWR|O_TRUNC|O_CREAT, 0);
//以每次打開文件清零和如不存在便建立就打開兩個輸出文件

 3:      int fdin = open("stdin.txt", O_RDWR, 0);
 4:      int tempin = dup(STDIN_FILENO);
 5:     int tempout = dup(STDOUT_FILENO), line = 1;
//對標準輸出輸入描述符表進行拷貝,防止系統清除其指向的文件表


 6:      char buf1[4096], buf2[4096];
 7:   
 8:      dup2(fdin, STDIN_FILENO);
9: dup2(fdout1, STDOUT_FILENO);
//重定向


10:      if (system("main1.exe") == 127)
11:          write(tempout, "NO EXE", 7);
12:      fdin = open("stdin.txt", O_RDWR, 0);
13:      dup2(fdin, STDIN_FILENO);
//可能有些同窗要問了這裏問什麼要對標準輸入重定向兩次,具體解釋略長參見後文。


14:      dup2(fdout2, STDOUT_FILENO);
15:      if (system("main2.exe") == 127)
16:          write(tempout, "NO EXE", 7);
17:      dup2(tempout, STDOUT_FILENO);

 //恢復標準輸出code

 

18:      lseek(fdout1, 0, SEEK_SET);
19:      lseek(fdout2, 0, SEEK_SET);

//重置文件讀取位置,具體解釋同十三行後。blog

 

3、對輸出文件的處理

 1 for(;;)
 2     {
 3         int n;
 4 
 5         if ((n = read(fdout1, buf1, 4096)) > 0 && read(fdout2, buf2, 4096) > 0)
 6         {
 7             int i, j = 0;
 8             char buffer[1024];
 9 
10             for (i = 0; i < n; i++)
11             {
12                 buffer[j++] = buf1[i];
13                 if (buf1[i] == buf2[i])
14                 {
15                     if (buf1[i] == '\n')
16                     {
17                         j = 0;
18                         line++;
19                     }
20                 }
21                 else
22                 {
23                     printf("The difference in line %d between stdout1.txt and stdout2.txt\n", line);
24                     buffer[j] = '\0';
25                     printf("%s\n", buffer);
26                     buffer[--j] = buf2[i];
27                     printf("%s\n", buffer);
28                     break;
29 
30                 }
31             }
32             if (i != n)
33                 break;
34 
35         }
36         else
37         {
38             printf("Can't find difference in this instance\n");
39             break;
40         }
41     }

 

4、對上文問題的解釋

以上的兩個問題都是因爲帶緩衝區的文件讀寫和不帶緩衝區的文件讀寫混用產生的問題。標準輸出和標準輸入是帶緩衝區的,而read和write函數不帶緩衝區,因此進行重定向時,一旦將不帶緩衝區的用read打開的輸入文件stdin.txt重定向到標準輸入,則輸入文件中的內容會被輸入到緩衝區中,引發當前讀寫文件位置的變化,下次程序main2.exe引用的時候就會出現錯誤。同理在輸出文件操做的時候也要進行當前讀寫位置的復原。

5、警告

本程序bug多多,但基本能用,尤爲是本人原先不熟悉windows下的一下編程,完成後才發現用windows寫一個bat程序要簡單的多,這就形成了在windows環境下以linux系統命令編寫的一個不三不四的對拍程序。

因爲程序寫的確實有點爛,主要目的原來是想救一救我被學校評測網站虐的慘不忍睹的C語言習題,順便熟悉一下進來學習的知識,因此想順便放上來分享一下,歡迎各位園友指出錯誤,必定虛心受教。

目前的bug有:若是一行超出1024b,就會發生溢出;有些狀況可能行號不太準確。

6、小感

第一次寫文章,排版各方面不太熟悉,但願各位諒解。

源代碼http://files.cnblogs.com/Bright-Star/main.zip

相關文章
相關標籤/搜索