使用檔案進行輸入輸出的兩種方式(演算法競賽入門經典第2章)
使用檔案進行輸入輸出的兩種方式:
1, 重定向
freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
上述語句將使得scanf從檔案input.txt讀入,printf寫入檔案output.txt。事實上,不只是scanf和printf,所有讀鍵盤輸入、寫螢幕輸出的函式都將改用檔案。
2, fopen
- 檔案輸入輸出:輸入輸出重定向;fopen。
- 標準輸入輸出:(也稱標準I/O,即直接讀鍵盤、寫螢幕)。
{演算法競賽入門經典}第二章 檔案操作 重定向及fopen版本
1, 從程式碼上看,重定向方法寫起來簡單,fopen稍顯複雜,但實際上兩者都是固定的語句。
2, 從靈活性看,只要用重定向方法,就全部是用檔案讀寫,不能再進行常規的標準輸入輸出。而fopen較靈活,可以同時讀寫檔案、標準輸入輸出(只要分別用fscanf,fprintf和scanf,printf就能共存,靈活性更強)。
3, 從程式碼特點上看:
a) 重定向方法需要注意#ifdef與#endif符號定義,從而從檔案讀寫轉換為標準輸入輸出讀寫比較方便。
b) fopen則需要注意要定義FILE*檔案指標,利用fopen開啟檔案,同時特別需要注意的是使用完畢後要使用fclose關閉檔案指標,從檔案讀寫改為標準輸入輸出需賦值fin=stdin;fout=stdout;同時將註釋掉fopen和fclose,修改稍顯複雜。
重定向版本並不算嚴格意義上的檔案操作(沒有定義檔案指標及沒有用檔案操作函式)
1,重定向版:
#include<stdio.h> #define INF 1000000000 #define LOCAL int main() { #ifdef LOCAL freopen("data.in","r",stdin); freopen("data.out","w",stdout); #endif int x,n=0,min,max,s=0; while(scanf("%d",&x)==1) { s+=x; if(x<min) min=x; if(x>max) max=x; n++; /*printf("x = %d, min = %d, max = %d\n", x, min, max);*/ } printf("%d %d %.3f\n",min,max,(double)s/n); return 0; }
(1)重定向的部分被寫在了#ifdef和#endif中。 其含義是:只有定義了符號LOCAL,才編譯兩條freopen語句。 (2)輸出中間結果的printf語句寫在了註釋中——它在最後版本的程式中不應該出現,但是又捨不得刪除它(萬一發現了新的bug,需要再次用它輸出中間資訊)。 將其註釋的好處是:一旦需要時,把註釋符去掉即可。
上面的程式碼在程式首部就定義了符號LOCAL,因此在本機測試時使用重定向方式讀寫檔案。
注意,注意啊,如果用重定向,一定要絕對路徑!用VC6或者CodeBlocks除錯的時候程式執行目錄不是程式的生成目錄!不寫絕對路徑,就沒有輸入,程式除錯時就卡在輸入上了!!!還有,是兩條反斜槓,兩條,不是一條!!!
#ifdef LOCAL freopen("D://input.txt","r",stdin); freopen("D://ouput.txt","w",stdout); #endif
2,fopen版
#include<stdio.h>
#define INF 1000000000
int main()
{
FILE *fin, *fout;
fin = fopen("data.in", "rb");
fout = fopen("data.out", "wb");
int x, n = 0, min = INF, max = -INF, s = 0;
while(fscanf(fin, "%d", &x) == 1)
{
s += x;
if(x < min) min = x;
if(x > max) max = x;
n++;
}
fprintf(fout, "%d %d %.3f\n", min, max, (double)s/n);
fclose(fin);
fclose(fout);
return 0;
}
雖然新內容不少,但也很直觀:先宣告變數fin和fout(暫且不用考慮FILE*),把scanf改成fscanf,第一個引數為fin;把printf改成fprintf,第一個引數為fout,最後執行fclose,關閉兩個檔案。
如果不允許使用重定向方式讀寫資料,應使用fopen和fscanf/fprintf進行輸入輸出。
重定向和fopen兩種方法各有優劣。 重定向的方法寫起來簡單、 自然,但是不能同時讀寫檔案和標準輸入輸出;fopen的寫法稍顯繁瑣,但是靈活性比較大(例如,可以反覆開啟並讀寫檔案)。 順便說一句,如果想把fopen版的程式改成讀寫標準輸入輸出,只需賦值“fin=stdin;fout=stdout;”即可,不要呼叫fopen和fclose(10)。