101
10 10 第第第第第第第 第第第第第第第 第第第第第第第第第 第第第第第 第第第第第第

10 檔案說明與處理

Embed Size (px)

Citation preview

Page 1: 10 檔案說明與處理

第第 1010 章 檔案說明與處理章 檔案說明與處理

檔案存取的基本觀念文字檔處理上機實習課程

Page 2: 10 檔案說明與處理

2

檔案結構 檔案結構

通常在作業系統的檔案管理中,是採用「樹狀結構」( Tree Structure )的方式來儲存各種資料檔案。

單一磁碟機可視為一棵倒立樹木,樹根的位置就如同磁碟機的根目錄。

在樹根底下可能會有「樹節」或「樹葉」,其中「樹節」可比喻為「資料夾」,而「樹葉」則視為「檔案」。

10-1 檔案存取的基本觀念

Page 3: 10 檔案說明與處理

3

在「樹節」中可能還會有「子樹節」來包含其它的「樹葉」,這也相對於「資料夾」中可能包含了「子資料夾」及「檔案」。

整個檔案結構會依照上述的方式逐漸往下發展,而形成一個完整的結構。

磁碟機中檔案結構如下圖所示:

10-1 檔案存取的基本觀念

Page 4: 10 檔案說明與處理

4

清楚了檔案結構後,當要表示某一個檔案的儲存路徑或位置時,通常會採用下面的表示方法:

例如: C:\WINDOWS\SYSTEM\CONTROL.TXT ,表示「 CONTROL.TXT 」檔案位於 C 磁碟下的「 WINDOWS 」資料夾,的「 SYSTEM 」子資料夾內。

10-1 檔案存取的基本觀念

磁碟代號 :\ 資料夾名稱 \ 資料夾名稱… \ 檔案名稱 . 副檔名

Page 5: 10 檔案說明與處理

5

資料流與緩衝區簡介資料流與緩衝區簡介

資料流 (stream) 主要是作為程式與周邊的資料傳輸管道,本章所談的都是指檔案資料流而言。

在進行 C 語言的檔案存取時,都會先進行「開啟檔案」的動作,這個動作即是在開啟資料流,而「關閉檔案」這個動作,就是在關閉資料流。

在 C 中主要是利用檔案處理函數來處理包括開啟檔案、讀取檔案、更新檔案與關閉檔案等動作。

這些檔案處理函數通常以是否利用到緩衝區來區隔。

10-1 檔案存取的基本觀念

Page 6: 10 檔案說明與處理

6

緩衝區 (buffer) 是記憶體中的一塊空間,當進行檔案輸入輸出時,其實並不會直接對磁碟進行存取,而是先開啟資料流,將磁碟上的檔案資訊放置到緩衝區中,而程式則從緩衝區中存取所需的資料。

緩衝區的設置是為了存取效率上的考量,因為記憶體的存取速度會比磁碟機來得快速。

10-1 檔案存取的基本觀念

Page 7: 10 檔案說明與處理

7

文字檔與二進位檔案文字檔與二進位檔案 (1)(1)

文字檔– 文字檔案會以字元編碼的方式進行儲存,在 Wi

ndows 作業系統中副檔名為 txt 的檔案,就是屬於文字檔案。

– 也是以二進位的方式儲存在磁碟中,只不過當您使用純文字編輯器開啟時,預設會進行字元比對的動作,並以相對應的編碼顯示文字檔案的內容。

10-1 檔案存取的基本觀念

Page 8: 10 檔案說明與處理

8

文字檔與二進位檔案文字檔與二進位檔案 (2)(2)

二進位檔案– 是將記憶體中的資料原封不動的儲存至檔案之中,適用於非字元為主的資料。

– 舉個例子來說,如果在記憶體中有兩個整數數值 511 與 255 要依序儲存至檔案中,則其儲存至檔案後的內容會如下所示(假設整數佔有兩個位元組的空間):

10-1 檔案存取的基本觀念

Page 9: 10 檔案說明與處理

9

檔案存取方式檔案存取方式

存取檔案的時候,可能是循序式( sequential access )的存取,也就是由上往下讀取檔案的內容,如果要儲存資料時,通常將資料附加在檔案的尾端,這種存取方式通常使用於文字檔案,而被存取的檔案則稱之為循序存取檔案。

另一種為隨機存取( random access ),您可以指定檔案讀取指標的位置,從檔案中的任一位置讀出或寫入資料,此時我們稱被存取的檔案為隨機存取檔案。

10-1 檔案存取的基本觀念

Page 10: 10 檔案說明與處理

10

檔案的開啟與關閉檔案的開啟與關閉 (1)(1)

要進行檔案的處理動作時,除了必須含括 stdio.h 標頭檔,還必須宣告一個指向檔案的 FILE型態指標。

FILE 是 stdio.h 中所定義的結構,下面所列出的是 stdio.h 所定義的 FILE 結構:

10-2 文字檔處理

Page 11: 10 檔案說明與處理

11

要進行檔案的存取,必先開啟資料流,也就是進行開啟檔案的動作,在標準 I/O 中要進行檔案的開啟,則是使用 fopen() 這個函數。

fopen() 函數會傳回一個結構指標位址,您只要將這個位址當作參數傳遞給其它函數就可以了,如果檔案開啟失敗,則會傳回一個 NULL 。

在呼叫 fopen() 函數時,必須將所宣告 FILE 結構指標變數用來接收 fopen() 函數的傳回值。

格式如下所示:

10-2 文字檔處理

檔案指標變數 =fopen(" 檔案名稱 "," 存取模式字串 ");

Page 12: 10 檔案說明與處理

12

此處的檔案名稱,可以包括檔案路徑,如果沒有指定則預設為目前的工作目錄。

而存取模式字串則如下所示:

10-2 文字檔處理

 

存取模式 說明r 開啟檔案進行讀取動作,不寫入任何內容w 產生一個新的檔案,如果有同名檔案存在,則該檔案會被丟棄a 開啟一個已存在的檔案,所寫入的檔案會附加在原檔案的尾端;

如果指定的檔案不存在,則產生一個新的檔案r+ 開啟一個已經存在的檔案,以進行讀取或修改w+ 產生一個新的檔案,以進行讀取或寫入,如果有同名檔案存在,

則該檔案會被丟棄a+ 開啟一個已存在的檔案,所寫入的檔案會附加在原檔案的尾端;

如果指定的檔案不存在,則產生一個新的檔案,作用與 a相同

 

Page 13: 10 檔案說明與處理

13

檔案處理完畢後,最好要記得關閉檔案。關閉檔案的指令宣告如下:

10-2 文字檔處理

fclose( 檔案指標變數 );

Page 14: 10 檔案說明與處理

14

檔案的開啟與關閉檔案的開啟與關閉 (2)(2)

程式範例:檔案開啟與關閉的基本範例: CH10_01.c

10-2 文字檔處理

Page 15: 10 檔案說明與處理

15

執行結果

10-2 文字檔處理

Page 16: 10 檔案說明與處理

16

程式解說

10-2 文字檔處理

第 6 行中建立檔案變數指標。第 10 行輸入準備開啟的檔案名稱。第 11 行宣告以唯讀方式開啟檔案。第 13 行如果檔案開啟成功,則不會傳回一個 NULL ,並且輸出「這個檔案開啟成功 ! 」,否則「找不到檔案 , 開啟失敗」。

Page 17: 10 檔案說明與處理

17

如果想要逐一將字元寫入檔案中,則可以使用 fputc() 函數,使用格式如下:

例如:

ch 為所要寫入的字元,而 fptr 為所開啟檔案的結構指標, fputc()若寫入字元失敗,則傳回 EOF值,否則就傳回寫入的字元值。

在 C 中, EOF(End Of File) 是表示資料結尾的常數,其值為 -1 ,定義在 stdio.h 標頭檔中。

fputc()fputc() 函數與函數與 fgetc()fgetc() 函數函數 (1)(1)10-2 文字檔處理

fputc( 字元變數 , 檔案指標變數 );

fputc(ch,fptr);

Page 18: 10 檔案說明與處理

18

fgetc() 函數的定義如下:

例如:

如果字元讀取成功,則傳回所讀取的字元值,否則就傳回 EOF ( End of File )。

10-2 文字檔處理

fgetc( 字元變數 , 檔案指標變數 );

fgetc(ch,fptr);

Page 19: 10 檔案說明與處理

19

fputc()fputc() 函數與函數與 fgetc()fgetc() 函數函數 (2)(2)

程式範例: fputc() 函數與 fgetc() 函數的基本範例: CH10_02.c

10-2 文字檔處理

Page 20: 10 檔案說明與處理

20

10-2 文字檔處理

Page 21: 10 檔案說明與處理

21

執行結果

程式解說

10-2 文字檔處理

第 11 行檢查檔案是否開啟成功。第 15 行如果輸入不為 Enter鍵,則繼續迴圈。第 16 行將字元寫入檔案。第 23~27 行逐字讀出字元。

Page 22: 10 檔案說明與處理

22

程式範例: fputc() 函數與 fgetc() 函數的拷貝檔案範例: CH10_03.c

10-2 文字檔處理

Page 23: 10 檔案說明與處理

23

10-2 文字檔處理

Page 24: 10 檔案說明與處理

24

執行結果

程式解說

10-2 文字檔處理

第 11 行以寫入方式開啟“油漆式記憶法拷貝版 .txt” ,並將 fptr1 指標指向此檔案。第 18 行從 fptr 所指向檔案逐一讀出字元 ch ,並在第 19行將 ch 字元寫入 fptr1 所指向檔案。第 27 行以 feof() 函數來判斷檔案是否結束,第 31 行以count 來控制每 30 個字元為一行輸出。

Page 25: 10 檔案說明與處理

25

使用 fputs() 函數將一個字串寫入至檔案中,使用格式如下:

例如:

fpus()fpus() 函數與函數與 fgets()fgets() 函數函數 (1)(1)10-2 文字檔處理

fputs(" 寫入字串 ", 檔案指標變數 );

File *fptr;char str[20];…..fputs(str,fptr);

Page 26: 10 檔案說明與處理

26

如果要讀取檔案中的一個字串,可使用 fgets()函數,使用格式如下:

例如:

10-2 文字檔處理

fgets(" 讀出字串 ", 字串長度 , 檔案指標變數 );

File *fptr;char str[20];int length;…..fgets(str,length,fptr);

Page 27: 10 檔案說明與處理

27

fpus()fpus() 函數與函數與 fgets()fgets() 函數函數 (2)(2)

程式範例: fputs() 函數與 fgets() 函數的基本範例: CH10_04.c

10-2 文字檔處理

Page 28: 10 檔案說明與處理

28

10-2 文字檔處理

Page 29: 10 檔案說明與處理

29

執行結果

10-2 文字檔處理

Page 30: 10 檔案說明與處理

30

程式解說

10-2 文字檔處理

第 18 行以 fgets() 函數寫入檔案,第 19 行則以 fgetc() 函數來每筆資料的尾端加上換行字元。第 24 行檢查檔案是否開啟成功 , 並宣告以新增模式寫入檔案。第 29 行以新增模式寫入檔案 , 會加在原檔案後方。第 37 行我們設定的讀取長度是 11 而不是 10 ,這是因為 fgets() 只會讀取 l1-1 的字串,並於最後一個位置加上‘ \0’ 字元,並且如果不是 NULL 則執行 while迴圈。第 40 行以 count 值來計算此檔案的資料筆數。

Page 31: 10 檔案說明與處理

31

fpus()fpus() 函數與函數與 fgets()fgets() 函數函數 (3)(3)

程式範例: fputs() 函數與 fgets() 函數的拷貝檔案範例: CH10_05.c

10-2 文字檔處理

Page 32: 10 檔案說明與處理

32

10-2 文字檔處理

Page 33: 10 檔案說明與處理

33

執行結果

程式解說

10-2 文字檔處理

第 14 行如果檔案未結束 , 則執行迴圈。第 17 行將 str 字串存入 fptr1 所指向的檔案。第 25 行以 fgets() 函數讀取 11 字元的字串,如果不是 NULL 則執行 while迴圈。第 27 行關閉檔案。

Page 34: 10 檔案說明與處理

34

fprintf()fprintf() 函數與函數與 fscanf()fscanf() 函數函數 (1) (1)

fprintf() 函數的使用格式如下:

例如 :

10-2 文字檔處理

fprintf( 檔案指標變數 ,格式化字串 ,變數 1,變數 2…);

File *fptr;int math,eng;float average;fprintf(fptr, "%d\t%d\t%f\n",math,enf,average);

Page 35: 10 檔案說明與處理

35

fscanff() 函數的使用格式如下:

例如 :

10-2 文字檔處理

fscanff(檔案指標變數 ,格式化字串 ,變數 1位址 ,變數 2位址… );

File *fptr;int math,eng;float average;fprintf(fptr, "%d\t%d\t%f\n",&math,&enf,&average);

Page 36: 10 檔案說明與處理

36

fprintf()fprintf() 函數與函數與 fscanf()fscanf() 函數函數 (2)(2)

程式範例: fprintf() 函數與 fscanf() 函數的宣告與應用範例: CH10_06.c

10-2 文字檔處理

Page 37: 10 檔案說明與處理

37

10-2 文字檔處理

Page 38: 10 檔案說明與處理

38

執行結果

10-2 文字檔處理

Page 39: 10 檔案說明與處理

39

程式解說

10-2 文字檔處理

第 4~10 行定義結構 , 這個 student 結構為全域性的結構型態。第 16~17 行宣告並初始化這 5 個學生的各種成績資料。第 20 行檢查檔案是否開啟成功來寫入。第 25 行以 fscanf() 函數寫入檔案。第 29 行檢查檔案是否開啟成功來讀取。第 35 行以 fscanf() 函數讀取檔案。

Page 40: 10 檔案說明與處理

40

fwrite()fwrite() 函數與函數與 fread()fread() 函數函數 (1)(1)

fwrite() 函數使用格式如下:

例如:

10-2 文字檔處理

fwrite("寫入資料位址 ","寫入資料單位大小 ","寫入資料的筆數 ",檔案指標變數 );

File *fptr;char str[20];int count;fwrite(str,sizeof(char),count,fptr);

Page 41: 10 檔案說明與處理

41

如果想要 fwrite() 函數所寫入的資料內容,就必須採取 fread() 函數來讀取檔案,才可以正確讀出有意義的資訊。使用格式如下:

10-2 文字檔處理

fread(" 寫入資料位址 "," 寫入資料單位大小 "," 寫入資料的筆數 ", 檔案指標變數 );

Page 42: 10 檔案說明與處理

42

fwrite()fwrite() 函數與函數與 fread()fread() 函數函數 (2)(2)

程式範例: fwite() 函數與 fread() 函數的宣告與應用範例: CH10_07.c

10-2 文字檔處理

Page 43: 10 檔案說明與處理

43

10-2 文字檔處理

Page 44: 10 檔案說明與處理

44

執行結果

程式解說

10-2 文字檔處理

第 15~16 行如果輸入不為 Enter鍵,則繼續迴圈,並將字元寫入字元陣列。第 18 行必須加上空字元。第 19 行以 fwrite() 函數寫入 str 字串。第 20 行 d 為一陣列名稱,可代表該陣列的位址。第 27 行以 fread() 函數讀出字串內容。第 31~32 行輸出所讀取陣列 d1陣列內容。

Page 45: 10 檔案說明與處理

45

我們可以直接製作個簡單的範例,看看如何使用 fwrite() 函數寫入二進位資料至檔案中,第 10 行是以 wb模式,表示開啟二進位檔案進行讀取動作,不寫入任何內容開啟,“ b” 表示為二進位模式。

以下是二進位檔的存取模式:

10-2 文字檔處理

存取模式 說明

rb 開啟二進位檔案進行讀取動作,不寫入任何內容wb 產生一個新的二進位檔案,如果有同名檔案存在,則該原檔案會

被丟棄,另開啟新檔案ab 開啟一個已存在的二進位檔案,所寫入的檔案會附加在原檔案的

尾端;如果指定的檔案不存在,則產生一個新的檔案

Page 46: 10 檔案說明與處理

46

fwrite()fwrite() 函數與函數與 fread()fread() 函數函數 (3)(3)

程式範例: fwrite() 函數寫入二進位資料檔的應用範例: CH10_08.c

10-2 文字檔處理

Page 47: 10 檔案說明與處理

47

執行結果

10-2 文字檔處理

Page 48: 10 檔案說明與處理

48

程式解說

10-2 文字檔處理

第 15 行由於 fwrite() 的緩衝區位址預設為 char 資料型態,所以在第 15 行中必須先經過型態轉換,並且每次讀取一個位元組。第 16 行以 fwrite() 函數寫入字串,第 17 行以 fwrite() 函數寫入陣列。

Page 49: 10 檔案說明與處理

49

fwrite()fwrite() 函數與函數與 fread()fread() 函數函數 (4)(4)

程式範例: fread() 函數與二進位檢視器的應用範例: CH10_09.c

10-2 文字檔處理

Page 50: 10 檔案說明與處理

50

10-2 文字檔處理

Page 51: 10 檔案說明與處理

51

執行結果

程式解說

10-2 文字檔處理

第 16 行每次讀取一個位元組。第 17 行如果小於 0xF ,於顯示上補 0 。第 22 行中每顯示 16 位元組換行。

Page 52: 10 檔案說明與處理

52

fwrite()fwrite() 函數與函數與 fread()fread() 函數函數 (5)(5)

程式範例: fread() 函數讀取二進位檔的應用範例: CH10_10.c

10-2 文字檔處理

Page 53: 10 檔案說明與處理

53

執行結果

10-2 文字檔處理

Page 54: 10 檔案說明與處理

54

程式解說

10-2 文字檔處理

第 16~18 行讀取字元、整數與整數陣列。第 20~22 行輸出字元、整數與整數陣列。

Page 55: 10 檔案說明與處理

55

每次使用檔案存取函數一次,檔案讀取游標都會往下一個位置移動,例如 rewind() 這個函數,它可以將檔案讀取游標返回檔案的開頭。使用格式如下:

像 fgetc() 函數讀取完畢後會移動一個位元組,而在 fgets() 函數中,由於我們的 length長度為 10 ,所以它一次會讀取 9 個位元組的長度(因為最後一個位元組必須填入 '\0' ),像這種讀取方式,可稱之為循序式讀取。

隨機存取檔案隨機存取檔案 (1)(1)10-2 文字檔處理

rewind(檔案指標變數 );

Page 56: 10 檔案說明與處理

56

檔案中也可以藉由 fseek() 函數來操作讀取游標,使用格式如下:

所謂位移量,單位是位元組,由游標起始點向前或向後的位移量。

而起點參數則是游標起始點設定位移量的計算起點。共有 3 種巨集常數,說明如下:

10-2 文字檔處理

fseek( 檔案指標變數 , 位移量 ,起點參數 );

巨集常數 常數值 說明

SEEK_SET 0 檔案開頭向後計算。SEEK_CUR 1 目前的游標位置向後計算。SEEK_END 2 檔案尾端向前計算。

Page 57: 10 檔案說明與處理

57

隨機存取檔案隨機存取檔案 (2)(2)

程式範例: fseek() 函數與移動讀取游標的應用範例: CH10_11.c

10-2 文字檔處理

Page 58: 10 檔案說明與處理

58

10-2 文字檔處理

Page 59: 10 檔案說明與處理

59

執行結果

程式解說

10-2 文字檔處理

第 16 行 SEEK_SET 常數的應用,第 18 行 SEEK_CUR 常數的應用。第 21 行 SEEK_END 常數的應用。

Page 60: 10 檔案說明與處理

60

隨機存取檔案隨機存取檔案 (3)(3)

程式範例: fseek() 函數與移動讀取游標來修正檔案中字串的範例: CH10_12.c

10-2 文字檔處理

Page 61: 10 檔案說明與處理

61

10-2 文字檔處理

Page 62: 10 檔案說明與處理

62

執行結果

程式解說

10-2 文字檔處理

第 10 行為了要能保留原有的字串,我們在檔案存取模式上設定為“ r+” ,表示可讀取檔案,並可修改檔案內容。第 17 行以 fseek() 函數來從檔案後端移動。第 20 行移到檔案最前端,也可以使用 fseek(fptr, 0, SEEK_SET) 指令來達到同樣效果。

Page 63: 10 檔案說明與處理

63

隨機存取檔案隨機存取檔案 (4)(4)

程式範例: fwrite() 函數與寫入一個結構的應用範例: CH10_13.c

10-2 文字檔處理

Page 64: 10 檔案說明與處理

64

10-2 文字檔處理

Page 65: 10 檔案說明與處理

65

執行結果

程式解說

10-2 文字檔處理

第 16~20 行讀入三筆學生資料。第 22 行以寫入方式開啟二進位檔。第 26~27 行以 fwrite() 函數寫入結構資料。

Page 66: 10 檔案說明與處理

66

隨機存取檔案隨機存取檔案 (5)(5)

程式範例: fread() 函數與讀出一個結構的應用範例: CH10_14.c

10-2 文字檔處理

Page 67: 10 檔案說明與處理

67

10-2 文字檔處理

Page 68: 10 檔案說明與處理

68

10-2 文字檔處理

Page 69: 10 檔案說明與處理

69

執行結果

程式解說

10-2 文字檔處理

第 16 行開啟一個已經存在的二進位檔案,以進行讀取或修改,也可以寫作 r+b 。第 28 行以 fseek() 函數移動從檔案開頭向後計算 (number-1)*sizeof(struct student) 位元組。第 40~42 行以 fwrite() 函數寫入檔案。

Page 70: 10 檔案說明與處理

70

無緩衝區檔案處理函數無緩衝區檔案處理函數 (1) (1)

無緩衝區檔案處理函數定義於 io.h 與 fcntl.h 中,其中 io.h 是無緩衝區檔案存取函數所定義的標頭檔,fcntl.h 是開啟模式常數所定義的標頭檔。

提醒大家如果要使用無緩衝區檔案處理函數,必須加入 io.h 、 fcntl.h 與 sys/stat.h三個檔案含括進來。

其中要開啟與關閉檔案,分別是使用 open() 函數與 close() 函數,首先我們來介紹 open() 函數的使用格式如下:

10-2 文字檔處理

open(" 檔案名稱 ", 開啟模式 , 存取屬性 );

Page 71: 10 檔案說明與處理

71

關閉檔案時,則將檔案處理代碼傳遞給 close()函數即可,如果 close() 函數執行成功,則傳回檔案處理代碼,若執行失敗則傳回 -1 。

使用格式如下:

例如:

10-2 文字檔處理

close( 檔案處理代碼 );

close(fpt1);

Page 72: 10 檔案說明與處理

72

無緩衝區檔案處理函數函數的寫入與讀取函數分別為 write() 與 read() 函數,其定義上與 fread() 與 fwrite() 函數是類似的,都可一次處理整個區塊的資料。使用格式如下:

例如:

10-2 文字檔處理

write( 檔案處理代碼 , 緩衝區變數 , 緩衝區變數大小位元組 );read( 檔案處理代碼 , 緩衝區變數 , 緩衝區變數大小位元組 );

write(fpt1, buffer, sizeof(buffer)); /* 在 fpt1 檔案 ,每次寫入 256 個位元組 */bytes=read(fptl, buffer, sizeof(buffer));/* 從 fpt1 檔案 ,每次讀取 256 個位元組, bytes 為實際的傳回讀取位元組 */

Page 73: 10 檔案說明與處理

73

無緩衝區檔案處理函數無緩衝區檔案處理函數 (2)(2)

程式範例:無緩衝區檔案處理的 write() 與 read() 函數範例: CH10_15.c

10-2 文字檔處理

Page 74: 10 檔案說明與處理

74

10-2 文字檔處理

Page 75: 10 檔案說明與處理

75

10-2 文字檔處理

Page 76: 10 檔案說明與處理

76

執行結果

程式解說

10-2 文字檔處理

第 3 行 O_CREAT 常數所定義的標頭檔。第 4 行無緩衝區檔案存取函數所定義的標頭檔。第 9 行自行設置緩衝區 , 一次可讀取 512 個位元組。第 10 行宣告兩個檔案處理代碼 , 與可處理的位元組數。第 21 行從 fpt1 檔案 ,每次讀取 256 個位元組。第 28 行以附加的方式開啟檔案。第 33 行新加一筆檔案內容。第 44 行從 fpt2 檔案 ,每次讀取 512 個位元組。

Page 77: 10 檔案說明與處理

77

上機實習課程上機實習課程 (1) (1)

上機實習範例: CH10_16.c– 請設計一程式來逐字讀取 test.txt 的檔案內容,並將所有英文字元以大寫及每行 20 個字元輸出。

10-3 上機實習課程

Page 78: 10 檔案說明與處理

78

10-3 上機實習課程

Page 79: 10 檔案說明與處理

79

執行結果

10-3 上機實習課程

Page 80: 10 檔案說明與處理

80

上機實習課程上機實習課程 (2)(2)

上機實習範例: CH10_17.c– 以下程式範例中,將檢視 fgetc() 讀取完畢後會移動一個位元組,而由於指定了 fgets() 的 lentgh長度為 10 ,所以它一次會讀取 9 個位元組的長度(因為最後一個位元組必須填入 '\0' )。

10-3 上機實習課程

Page 81: 10 檔案說明與處理

81

10-3 上機實習課程

Page 82: 10 檔案說明與處理

82

執行結果

10-3 上機實習課程

Page 83: 10 檔案說明與處理

83

上機實習課程上機實習課程 (3)(3)

上機實習範例: CH10_18.c– 現在有一「學生成績檔 .txt 」,分別存放學號、姓名與成績,其中學號 (10001~10005) 與成績是以整數格式。

– 而姓名則宣告為可存放 20 字元,請利設計一程式,利用 fscanf() 函數由檔案中取得指定的資料,並可針對學號進行成績查詢的動作,或是列出大於某個成績的紀錄,在此使用了 rewind() 函數,它可以將檔案讀取游標返回檔案的開頭。

10-3 上機實習課程

Page 84: 10 檔案說明與處理

84

10-3 上機實習課程

Page 85: 10 檔案說明與處理

85

10-3 上機實習課程

Page 86: 10 檔案說明與處理

86

執行結果

10-3 上機實習課程

Page 87: 10 檔案說明與處理

87

上機實習課程上機實習課程 (4)(4)

上機實習範例: CH10_19.c– 以下這個程式範例使用命令列引數來任意指定所要的檔案名稱,並實作所有的錯誤檢查動作,包括開啟檔案、讀取與寫入、關閉檔案等。

– 請進入 Windows 作業系統下的命令提示字元視窗。– 再利用 Dos 指令 ( 如 cd 指令 )切換到此程式執行檔所在目錄。

– 當執行時,建議輸入以下指令:

10-3 上機實習課程

C:\>CH10_19 報導內容 .txt

Page 88: 10 檔案說明與處理

88

10-3 上機實習課程

Page 89: 10 檔案說明與處理

89

執行結果

10-3 上機實習課程

Page 90: 10 檔案說明與處理

90

上機實習課程上機實習課程 (5)(5)

上機實習範例: CH10_20.c– 延續上題,以下這個程式範例也是使用命令列引數來任意指定所要的檔案名稱,並使用它來計算指定檔案的容量。

– 由於是 fgetc() 函式一次可以讀取一個字元,也就是一個位元組的大小,所以只要每讀出一個位元組計數一次即可。建議輸入以下指令:

10-3 上機實習課程

C:\>CH10_20 報導內容 .txt

Page 91: 10 檔案說明與處理

91

10-3 上機實習課程

Page 92: 10 檔案說明與處理

92

執行結果

10-3 上機實習課程

Page 93: 10 檔案說明與處理

93

上機實習課程上機實習課程 (6)(6)

上機實習範例: CH10_21.c– 延續上題,以下這個程式範例是利用 fgetc() 函式一次讀取一個位元的特性,製作一個檔案複製程式,這個程式可以複製文字檔或是二進位檔。

– 請注意!在開啟檔案時,必須以二進位的方式開啟,也就是在存取模式上加上“ b” 表示二進位模式,否則的話在複製二進位檔案時,檔案資訊將會不完全。

– 建議輸入以下指令:

10-3 上機實習課程

C:\>CH10_21 報導內容 .txt 報導內容拷貝 .txt

Page 94: 10 檔案說明與處理

94

10-3 上機實習課程

Page 95: 10 檔案說明與處理

95

執行結果

10-3 上機實習課程

Page 96: 10 檔案說明與處理

96

上機實習課程上機實習課程 (7)(7)

上機實習範例: CH10_22.c– 延續上題,我們知道在網路上有一些看圖程式,多半具有可以直接比較兩個圖片的內容是否相同的功能。

– 其實就是直接比較兩個圖片檔案中每一個位元組,如果每個位元組的值都相同,當然表示兩張圖片內容一樣。

– 以下這個程式範例是使用命令列引數來讓您進行檔案的比對,看看兩個檔案內容是否一樣。

– 建議輸入以下指令:

10-3 上機實習課程

C:\>CH10_22 score.bin scorecopy.bin

Page 97: 10 檔案說明與處理

97

10-3 上機實習課程

Page 98: 10 檔案說明與處理

98

執行結果

10-3 上機實習課程

Page 99: 10 檔案說明與處理

99

上機實習課程上機實習課程 (8)(8)

上機實習範例: CH10_23.c– 以下這個程式片段是利用無緩衝區檔案處理函式寫入字串至檔案中,然後再開啟相同的檔案讀出所寫入的字串,我們設定了 buffer 緩衝區以暫存寫入或讀出的字串。

10-3 上機實習課程

Page 100: 10 檔案說明與處理

100

10-3 上機實習課程

Page 101: 10 檔案說明與處理

101

執行結果

10-3 上機實習課程