當咱們求解acm題目時,一般在設計好算法和程序後,要在調試環境(例如VC等)中運行程序,輸入測試數據,當能獲得正確運行結果後,纔將程序提交到oj中。但因爲調試每每不能一次成功,每次運行時,都要從新輸入一遍測試數據,對於有大量輸入數據的題目,輸入數據須要花費大量時間。 ios
一個好的方法是用文件一一把輸入數據保存在 文件中,輸出數據也保存在文件中。這樣,只要事先把輸入數據保存在文件中,就沒必要每次從新輸入了;數據輸出在文件中也避免了「輸出太多,一卷屏前面的就看不見了」這樣的尷尬,運行結束後,慢慢瀏覽輸出文件便可。若是有標準答案文件,還能夠進行文件比較」,而無須編程人員逐個檢查輸出是否正確。事實上,幾乎全部算法競賽的輸入數據和標準答案都是保存在文件中的。使用文件最簡單的方法是使用輸入輸出重定向,只需在main函數的入口處加入如下兩條語句:算法
freopen("input.txt","r", stdin) ;編程
freopen("output.txt","w", stdout) ;函數
函數名:freopen
聲明:FILE *freopen( const char *path, const char *mode, FILE *stream );
所在文件: stdio.h
參數說明:
path: 文件名,用於存儲輸入輸出的自定義文件名。
mode: 文件打開的模式。和fopen中的模式(如r-只讀, w-寫)相同。
stream: 一個文件,一般使用標準流文件。
返回值:成功,則返回一個path所指定文件的指針;失敗,返回NULL。(通常能夠不使用它的返回值)
功能:實現重定向,把預約義的標準流文件定向到由path指定的文件中。標準流文件具體是指stdin、stdout和stderr。其中stdin是標準輸入流,默認爲鍵盤;stdout是標準輸出流,默認爲屏幕;stderr是標準錯誤流,通常把屏幕設爲默認。測試
上述語句將使得scanf從文件input.txt 讀入,printf 寫入文件output.txt。事實上,不僅是scanf和printf,全部讀鍵盤輸入、寫屏幕輸出的函數都將改用文件。儘管這樣作很方便,並非全部算法競賽都容許用程序讀寫文件。甚至有的競賽容許訪問文件,但不容許用freopen這樣的重定向方式讀寫文件。參賽以前請仔細閱讀文件讀寫的相關規定。spa
下面以在VC下調試「計算a+b」的程序舉例。
【C語法】debug
1 #include <stdio.h>
2 int main() 3 { 4 int a,b; 5 freopen("debug\\in.txt","r",stdin); //輸入重定向,輸入數據將從in.txt文件中讀取
6 freopen("debug\\out.txt","w",stdout); //輸出重定向,輸出數據將保存在out.txt文件中
7 while(scanf("%d %d",&a,&b)!=EOF) 8 printf("%d\n",a+b); 9 fclose(stdin);//關閉文件
10 fclose(stdout);//關閉文件
11 return 0; 12 }
【C++語法】設計
1 2 #include <stdio.h>
2 3 #include <iostream.h>
3 4 int main() 4 5 { 5 6 int a,b; 6 7 freopen("debug\\in.txt","r",stdin); //輸入重定向,輸入數據將從in.txt文件中讀取
7 8 freopen("debug\\out.txt","w",stdout); //輸出重定向,輸出數據將保存在out.txt文件中
8 9 while(cin>>a>>b) 9 10 cout<<a+b<<endl; // 注意使用endl
10 11 fclose(stdin);//關閉文件
11 12 fclose(stdout);//關閉文件
12 13 return 0; 13 14 }
freopen("debug\\in.txt","r",stdin)的做用就是把標準輸入流stdin重定向到debug\\in.txt文件中,這樣在用scanf或是用cin輸入時便不會從標準輸入流讀取數據,而是從in.txt文件中獲取輸入。只要把輸入數據事先粘貼到in.txt,調試時就方便多了。
相似的,freopen("debug\\out.txt","w",stdout)的做用就是把stdout重定向到debug\\out.txt文件中,這樣輸出結果須要打開out.txt文件查看。指針
提示調試
請在比賽以前瞭解文件讀寫的相關規定:是標準輸入輸出(也稱標II/O,即直接讀鍵盤、寫屏幕), 仍是文件輸入輸出?若是是文件輸入輸出,是否禁止用重定向方式的問文件?
須要說明的是:
1. 在freopen("debug\\in.txt","r",stdin)中,將輸入文件in.txt放在文件夾debug中,文件夾debug是在VC中創建工程文件時自動生成的調試文件夾。若是改爲freopen("in.txt","r",stdin),則in.txt文件將放在所創建的工程文件夾下。in.txt文件也能夠放在其餘的文件夾下,所在路徑寫正確便可。
2. 能夠不使用輸出重定向,仍然在控制檯查看輸出。
3. 程序調試成功後,提交到oj時不要忘記把與重定向有關的語句刪除。
若是比賽中要求用文件輸入輸出,但禁止用重定向的方式,又當如何呢?
在算法競賽中,若是不容許使用重定向方式讀寫數據,應使用fopen和fscant,fprintf進行輸入輸出。
咱們仍是之前面的例子爲例:
【C語法】
1 #include <stdio.h>
2 int main() 3 { 4 int a,b; 5 FILE *fin, *fout; 6 fin = fopen("debug\\in.txt","rb");//debug\\in.txt 你的測試文件的實際路徑
7 fout = fopen("debug\\out.txt","wb");// 8 while(fscanf(fin,"%d%d",&a,&b) == 2) 9 fprintf(fout,"%d \n",a+b); 10 fclose(stdin);//關閉文件
11 fclose(stdout);//關閉文件
12 return 0; 13 }
【C++語法】
1 #include <iostream>
2 #include <fstream>
3 using namespace std; 4 int main() 5 { 6 fstream fin,fout;//定義一個文件輸入輸出流對象
7 int a,b; 8 fin.open("debug\\in.txt",ios::in);//debug\\in.txt 你的測試文件的實際路徑
9 fout.open("debug\\out.txt",ios::out); 10 while(!fin.eof()) 11 { 12
13 fin>>a>>b; 14 if(fin.eof() == true)//若是文件到達末尾退出 eof()是文件流中的錯誤處理函數,它遇到文件結尾會返回true(一個非零值)。
15 break; 16 fout<<a+b<<endl; 17 } 18
19 fin.close();//關閉文件
20 fout.close();//關閉文件
21 return 0; 22 }
重定向和fopen兩種方法各有優劣。重定向的方法寫起來簡單、天然,可是不能同時讀寫文件和標準輸入輸出; fopen 的寫法稍顯繁瑣,可是靈活性比較大(例如,能夠反覆打開開讀寫文件)。
【提示】
若是想把fopen版的程序改爲讀寫標準輸入輸出,只需賦值"fin = stdin; fout = stdout;" 便可,不要調用fopen和fclose。