格式化讀寫檔案

就如同 scanf()printf() 分別對 stdin 和 stdout 做格式化的輸入與輸出,fscanf()fprintf() 也就分別對檔案做格式化的輸入與輸出,只要指定了檔案指標即可。 以下這個程式,再度改寫做敘述統計的程式 stats-scanf.c, 使得它從檔案中讀取輸入資料。假設那個檔案是 grade.3。 我們不再重複 istats(),請讀者自己去抄過來補上。


#include <stdio.h>
#include <math.h>
  
/* 測試 fscanf()  (stats-fscanf.c) */
#define FILENAME "grade.3"
#define DIM 512
void istats(int[], int);
  
main() {
    int i, n=0, x[DIM];
    FILE *fp;
    if ((fp = fopen(FILENAME, "r")) == NULL)
        printf("File is not readable.\n");
    else {
        while(fscanf(fp, "%d", &i) != EOF)
            x[n++] = i;
        istats(x, n);
    }
    fclose(fp);
}

我們已經知道,一個檔案不可以既讀又寫。 如果我們要更新一個檔案,先讀一些資料,再修改一些資料,怎麼辦呢? 正確的作法是以 "r" 模式打開舊檔, 以 "w" 模式打開新檔, 把需修改後的資料寫入新檔。如果一切無誤,再 mv 新檔到舊檔。 以下我們示範將 grade.3 裡面所有介於 20 和 59 之間的數值換成 60*, 置換後的檔案是 grade.3tmp


#include <stdio.h>
   
/* 測試 fprintf()  (test-fprintf.c) */
#define INFILE "grade.3"
#define OUTFILE "grade.3tmp"
  
main() {
    int i;
    FILE *fin, *fout;
    if ((fin = fopen(INFILE, "r")) == NULL)
        printf("%s is not readable.\n", INFILE);
    else if ((fout = fopen(OUTFILE, "w")) == NULL)
        printf("%s is not writable.\n", OUTFILE);
    else {
        while(fscanf(fin, "%d", &i) != EOF) {
            if ((i >= 20) && (i < 60))
                fprintf(fout, "60*\n");
            else
                fprintf(fout, "%d\n", i);
        }
    }
    fclose(fin);
    fclose(fout);
}

注意上面 printf()fprintf() 的用法。 如果檢查 grade.3tmp 正確無誤,則可以說
mv grade.3tmp grade.3
其實上述 UNIX 指令也可以自動化,由 C 程式完成,我們以後再談。

習題

[ 前一節 ]‧[ 後一節 ]‧[ 回目錄 ]



注意:此處所有文件均為原著,個別的版權宣告日後會一一公布, 整體版面設計亦尚未完成。但仍請勿抄襲文字與圖片,以免觸犯著作權法。

Created: Feb 28, 2001
Last Revised: Feb 28, 2001
© Copyright 2001 Wei-Chang Shann 單維彰

shann@math.ncu.edu.tw