280 likes | 411 Views
第十三章. 檔案. 檔案 I/O 的基本觀念. 檔案 I/O 的流程 定義指向 FILE 結構的指標 開啟一檔案 呼叫檔案 I/O 庫存函數以進行檔案的處理 關閉檔案 FILE 結構 此結構宣告於 <stdio.h> 標頭檔中. 檔案 I/O 的基本觀念. FILE 結構 /* Definition of the control structure for streams */ typedef struct {
E N D
第十三章 檔案
檔案 I/O 的基本觀念 • 檔案I/O的流程 • 定義指向FILE結構的指標 • 開啟一檔案 • 呼叫檔案I/O庫存函數以進行檔案的處理 • 關閉檔案 • FILE結構 • 此結構宣告於<stdio.h>標頭檔中
檔案 I/O 的基本觀念 • FILE結構 /* Definition of the control structure for streams */ typedef struct { int level; /* fill/empty level of buffer */ unsigned flags; /* File status flags */ char fd; /* File descriptor */ unsigned char hold; /* Ungetc char if no buffer */ int bsize; /* Buffer size */ unsigned char *buffer; /* Data transfer buffer */ unsigned char *curp; /* Current active pointer */ unsigned istemp; /* Temporary file indicator */ short token; /* Used for validity checking */ } FILE; /* This is the FILE object */
檔案字元 I/O /* File name: ex13-2a.c */ #include <stdio.h> #include <conio.h> #include <stdlib.h> int main() { FILE *fptr; char ch; fptr = fopen(“c:\\tremp\\test.dat”, “w”); while((ch = getche()) != ‘‘) fputc(ch, fptr); fclose(fptr); }
檔案字元 I/O • 程式解說 (1) FILE *fptr; /* 流程一 */ • 此敘述表示定義一fptr為指向FILE結構的指標 (2) fptr=fopen(“c:\\tremp\\test.dat”, “w”); /* 流程二 */ • 此敘述為開啟檔案之功用,其中fopen具有二個參數,第一個參數是檔名;第二個為檔案的存取模式 (3) fputc(ch, fptr); • 此敘述為檔案I/O的庫存函數,主要是將ch變數內容放到fptr所指的檔案(即為test.dat) (4) fclose(fptr); • 此敘述表示將fptr所指的檔案關閉
檔案字元 I/O • 檔案的存取模式(文字檔) • 二進位檔的存取模式 • rb、wb、ab • 其它的存取模式 • r+、w+、a+
檔案字元 I/O /* File name: ex13-2b.c */ #include <stdio.h> #include <stdlib.h> int main() { FILE *fptr; char ch; fptr = fopen("c:\\temp\\test.dat", "r"); while((ch = fgetc(fptr)) != EOF) printf("%c", ch); fclose(fptr); }
檔案字元 I/O • 程式解說 • 此程式是將檔案中的資料讀取出來,並配合標準的輸出,使其資料示在螢幕上 • while( ( ch = fgetc(fptr) ) != EOF ) 此敘述主要是利用一while迴圈,將fptr所指的字元指定給ch,判斷ch是否為EOF,若不是,則印此字元,直到檔案結束為止
檔案字串 I/O • 檔案字串I/O • 當使用者輸入資料是以字串為單位時,字串的I/O是您最佳的選擇 • C提供的檔案字串I/O函數 • fputs() 此函數的功能是將字串資料寫入所指的檔案中,如範例ex12-3a.c • fgets() 此函數的功能是從一指定的檔案中讀取字串,如範例ex12-3b.c
檔案字串 I/O /* File name: ex13-3a.c */ #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { FILE *fptr; char str[81]; fptr = fopen("c:\\temp\\str.dat", "w"); while(strlen(gets(str)) > 0) { fputs(str, fptr); fputs("\n", fptr); } fclose(fptr); }
檔案字串 I/O • 程式解說 (1) fputs(str, fptr); • 此敘述會將str陣列的資料寫入fptr所指的檔案中 • 此函數需要二個參數,第一個為字串參數;第二個為指向FILE結構的檔案指標 (2) strlne(gets(str)) > 0 • 判斷您輸入的字串是否大於0,若不是大於0,表示您未輸入字串就按「Enter」鍵,此時程式便將檔案關閉,若輸入字串大於0,才執行fputs函數
檔案的字串 I/O /* File name: ex13-3b.c */ #include <stdio.h> #include <stdlib.h> int main() { FILE *fptr; char str[81]; fptr = fopen("c:\\temp\\str.dat", "r"); while(fgets(str, 80, fptr) != NULL) printf("%s", str); fclose(fptr); }
檔案字串 I/O • 程式解說 (1) fgets(str, 80, fptr); • 此敘述會從fptr所指的檔案中,一次讀取80個字串長度的str陣列資料 • 此函數需要三個參數,第一個為字串參數;第二個參數表示一次讀取的字串長度;第三個為指向FILE結構的檔案指標 (2) strlne(gets(str)) > 0 • 判斷您輸入的字串是否大於0,若不是大於0,表示您未輸入字串就按「Enter」鍵,此時程式便將檔案關閉,若輸入字串大於0,才執行fputs函數
檔案的字串 I/O • 判斷開啟檔案是否成功? if( ( fptr = fopen("c:\\temp\\str.dat", "w") ) == NULL ) { printf("Can\'t open c:\\temp\\str.dat"); exit(1); } • 當呼叫fopen失敗時,系統會傳回NULL值回來,此外它會印出一訊息並呼叫exit函數終止程式執行 • 參數若為0,表示正當結束,否則為不正常的結束
檔案的格式化 I/O • 檔案的格式化I/O • 主要是用於當輸入的資料是混合性的時候 • C提供的檔案格式化I/O函數 • fprintf() • fscanf() • 這兩個函數與printf()和scanf()很相似,只是這兩個函數多了一個指向檔案的指標
檔案的格式化 I/O • fprintf()函數 • 主要是將資料寫入到檔案中 • 語法如下: fprintf( fptr, "%s %d", id, score ); 此敘述表示將id和score一併寫入fptr所指的檔案中 • 範例ex13-4a.c
檔案的格式化 I/O • fscanf()函數 • 主要是將檔案中的資料讀取出來 • 語法如下: fscanf( fptr, "%s %d", id, &score ) 此敘述表示從fptr所指的檔案中讀取id和score • 範例ex13-4b.c
檔案區段 I/O • 檔案區段I/O • 主要用於當運作的資料為一區段,如結構、陣列或結構陣列…等等 • 此類I/O可設定區段的大小及一次要拿多少個區段,這樣會讓讀取更有效率 • C提供的檔案區段I/O • fwrite() • fread()
檔案區段 I/O • fwrite()函數 • 此函數會將某個區段的資料一次寫入到檔案中 • 語法如下: fwrite( &student, sizeof(student), 1, fptr ) 其中第一個參數為要寫入的資料;第二個參數為區段的大小;第三個參數為一次要寫入的區段數目;第四個參數為指向寫入檔案的指標 • 範例ex13-5a.c
檔案區段 I/O • fread()函數 • 此函數會從檔案中讀取一個區段的資料到,並儲存於程式的變數中 • 語法如下: fread(&student, sizeof(student), 1, fptr) 其中第一個參數是儲存從檔案中讀取的資料;第二個參數為讀取的區段大小;第三個參數為一次要讀取的區段數目;第四個參數為指向被讀取檔案的指標
隨機存取 • 隨機存取 • 讓檔案資料的存取可以依使用者的意思隨心所欲的尋找 • 隨機存取函數 • fseek() • 範例ex13-6a.c
隨機存取 • fseek 函數 • 語法如下: fseek(fptr, offset, 0) • 此函數包含三個參數,第一個參數為指向檔案的指標;第二個參數為位移的bytes數;第三個參數表示從何處開始搜尋 • 第三個參數可分為三種 • SEEK_SET或0,表示從檔頭開始搜尋 • SEEK_CUR或1,表示從目前的位置開始搜尋 • SEEK_END或2,表示從檔尾開始搜尋 • fseek函數的失敗傳回值為非零值
文字檔與二進位檔的差異 • 文字檔與二進位檔的差異 • 換行,如範例ex13-7a.c • 檔案結尾,如範例ex13-7c.c
文字檔與二進位檔的差異 • 換行 • 文字檔的換行字元 ‘\n’是由CR (carriage return) /LF(line feed)組成CR/LF分別對應到ASCII十進位碼的13與10,故儲存時在檔案中會佔2 bytes;而讀取時則將CR/LF兩個字元轉為在 ‘\n’一個字元 • 二進位檔寫入換行字元 '\n' 僅記錄LF(亦即ASCII碼的10),佔1 byte的儲存空間
文字檔與二進位檔的差異 • 檔案結尾 • 文字檔遇到Ctrl-Z(十進位ASCII碼26)時,會視為檔案的結束 • 二進位檔則直接以檔案長度來判定檔案是否結束
檔案指標在何處 • 檔案指標函數 • ftell() 此函數可以回傳目前檔案指標位置 • 語法如下: curpos = ftell(fptr) 此函數需要一個指向檔案的檔案指標;其中curpos為一個檔案指標 • 此函數失敗之傳回值為-1L • 範例ex13-8a.c
重置檔案指標 • 重置檔案指標函數 • rewind() 此函數可使檔案指標返回檔案的開頭 • 語法如下: rewind(fptr); 此敘述會將檔案指標fptr移回檔案開頭 • 範例ex13-9a.c
偵察檔案指標的運作 • 偵察檔案指標函數 • ferror() 此函數可偵察檔案指標在最近一次寫入或讀取資料動作時是否正確的執行 • 語法如下: ferror(fptr); 此敘述會偵察檔案指標所執行的動作是否正確 • 若有錯誤則可利用perror印出錯誤訊息,再呼叫clearerr函數重設檔案錯誤旗號為0 • 範例ex13-10a.c