就如同 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); }
mv grade.3tmp grade.3其實上述 UNIX 指令也可以自動化,由 C 程式完成,我們以後再談。
習題
注意:此處所有文件均為原著,個別的版權宣告日後會一一公布, 整體版面設計亦尚未完成。但仍請勿抄襲文字與圖片,以免觸犯著作權法。
Created: Feb 28, 2001
Last Revised: Feb 28, 2001
© Copyright 2001 Wei-Chang Shann 單維彰