第十三章 檔案. 檔案 i/o 的基本觀念 檔案 i/o 的流程 定義指向 file...
Post on 22-Dec-2015
270 views
TRANSCRIPT
第十三章
檔案
檔案 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+
存取模式 作用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 印出錯誤訊息,再呼叫 cl
earerr 函數重設檔案錯誤旗號為 0 範例 ex13-10a.c