1. 程式人生 > >使用檔案進行輸入輸出的兩種方式(演算法競賽入門經典第2章)

使用檔案進行輸入輸出的兩種方式(演算法競賽入門經典第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)。