860 likes | 934 Views
程式設計. 博碩文化出版發行. 第十章 檔案的輸入與輸出. 課前指引 當 C 的程式執行完畢之後,所有儲存在記憶體的資料都會消失,這時如果需要將執行結果儲存在不會揮發的儲存媒體上 ( 如硬碟等 ) , 必須透過檔案模式來加以保存。. 章節大綱. 10-1 有緩衝區的輸入與輸出函數. 10-2 無緩衝區的輸入與輸出. 10-3 檔案的應用與實務. 備註:可依進度點選小節. 10-1 有緩衝區的輸入與輸出函數. C 的檔案處理函數主要區分為以下兩大類: 有緩衝區的輸出與輸入 無緩衝區的輸出與輸入. 10-1 有緩衝區的輸入與輸出函數.
E N D
程式設計 博碩文化出版發行
第十章 檔案的輸入與輸出 課前指引 當C的程式執行完畢之後,所有儲存在記憶體的資料都會消失,這時如果需要將執行結果儲存在不會揮發的儲存媒體上(如硬碟等),必須透過檔案模式來加以保存。
章節大綱 10-1 有緩衝區的輸入與輸出函數 10-2 無緩衝區的輸入與輸出 10-3 檔案的應用與實務 備註:可依進度點選小節
10-1 有緩衝區的輸入與輸出函數 • C的檔案處理函數主要區分為以下兩大類: • 有緩衝區的輸出與輸入 • 無緩衝區的輸出與輸入
10-1 有緩衝區的輸入與輸出函數 • 有緩衝區的輸出入函數如下所示:
10-1 有緩衝區的輸入與輸出函數 • fopen()與fclose()函數 • C語言中必須透過FILE型態的指標來操作檔案開關讀寫。FILE是一種指標型態,宣告方式如下: • FILE所定義的指標變數用來指向目前stream的位置,所以C語言中有關於檔案輸出入的函數,多數都需搭配宣告此資料型態運用。 FILE *stream;
10-1 有緩衝區的輸入與輸出函數 • fopen()與fclose()函數 • 接下來要進行檔案存取,首先必須開啟資料流,也就是進行開啟檔案的動作。也就是說,所有的檔案讀寫動作,都必須先開啟檔案,才能再繼續接下來的讀寫動作。指令如下: FILE * fopen ( const char * filename const char * mode );
10-1 有緩衝區的輸入與輸出函數 • fopen()與fclose()函數 • 參數說明 • filename:指定檔案名稱。 • Mode是指:開啟檔案的模式,至於開啟模式字串,在文字檔的存取上主要以六種模式為主,如下表所示:
10-1 有緩衝區的輸入與輸出函數 • fopen()與fclose()函數 • 當執行完檔案的讀寫後,應該確實的透過fclose()關閉使用中的檔案,才不會造成檔案被鎖定或是資料紀錄不完全的情形發生。指令如下: • 參數說明 • stream:指定資料流物件指標 • 當資料流正確被關閉時,回傳數值為0,如果資料流關閉錯誤,將引發錯誤或是回傳EOF。 intfclose ( FILE * stream );
10-1 有緩衝區的輸入與輸出函數 • 範例CH10_01.c
10-1 有緩衝區的輸入與輸出函數 • 執行結果 • 程式解說 • 第6行宣告一個指標形態的變數,變數名稱為pFile。 • 第8行是以讀取方式開啟檔案。 • 第9行透過判斷指標變數是否為NULL來確認檔案是否存在。 • 第11行開啟檔案後程式結束前,應透過fclose()函數關閉檔案。
10-1 有緩衝區的輸入與輸出函數 • 範例CH10_02.c
10-1 有緩衝區的輸入與輸出函數 • 執行結果 • 程式解說 • 第6行宣告一個指標形態的變數,變數名稱pFile。 • 第8行以讀取方式開啟檔案。 • 第11行關閉檔案。
10-1 有緩衝區的輸入與輸出函數 • fputc()函數。當寫入字元失敗時,則傳回EOF值,否則就傳回所寫入的字元。fputc()函數只會將參數中的字元寫入資料流,一次一個字元。指令如下: • 參數說明 • character:字元代表的ASCII碼。 • stream: 指定資料流物件指標。 int fputc ( int character, FILE * stream );
10-1 有緩衝區的輸入與輸出函數 • 範例CH10_03.c
10-1 有緩衝區的輸入與輸出函數 • 執行結果 • 程式解說 • 第6行宣告一個指標形態的變數,變數名稱pFile。 • 第8行以寫入方式開啟檔案。 • 第11行以putc()函數寫入一個字元,ASCII為65。
10-1 有緩衝區的輸入與輸出函數 • 範例CH10_04.c
10-1 有緩衝區的輸入與輸出函數 • 執行結果 • 程式解說 • 第6行宣告一個指標形態的變數,變數名稱pFile。 • 第9行以寫入方式開啟檔案。 • 第12~13行以for迴圈與putc()函數將資料儲存到所指定的檔案。
10-1 有緩衝區的輸入與輸出函數 • fgetc()函數 • fgetc()函數可從檔案資料流中一次讀取一個字元,然後將讀取游標往下一個字元移動,讀取字元正常時,回傳該字元ASCII碼。讀取完後指標會指向下一個位址,並且逐步將檔案的內容讀出。當需要更有效率的讀取或處理資料時,可使用此函數。指令如下: • 參數說明 • stream: 指定資料流物件指標。 int fgetc ( FILE * stream );
10-1 有緩衝區的輸入與輸出函數 • 範例 CH10_05.c
10-1 有緩衝區的輸入與輸出函數 • 執行結果 • 程式解說 • 第6行宣告一個指標形態的變數,變數名稱pFile。 • 第10行以讀取方式開啟檔案。 • 第13~16行EOF值利用while迴圈與EOF值執行判斷式,並逐字讀出檔案中資料。
10-1 有緩衝區的輸入與輸出函數 • 範例CH10_06.c
10-1 有緩衝區的輸入與輸出函數 • 執行結果 • 程式解說 • 第8行檢查檔案是否開啟成功。 • 第11行利用while迴圈判斷檔案是否讀取完畢。 • 第12行一次讀取一個字元,逐步將文字檔內容讀出。
10-1 有緩衝區的輸入與輸出函數 • fputs()函數與fgets()函數 • 我們也可以使用fputs()函數將一個字串寫入至檔案中,使用格式如下: • 例如: fputs("寫入字串", 檔案指標變數); File *fptr; char str[20]; ….. fputs(str,fptr);
10-1 有緩衝區的輸入與輸出函數 • 範例CH10_07.c
10-1 有緩衝區的輸入與輸出函數 • 執行結果 • 程式解說 • 第6行宣告一個指標形態的變數,變數名稱pFile。 • 第8行以新增方式開啟檔案。 • 第11行以fputs()函數寫入資料到指定的檔案中。
10-1 有緩衝區的輸入與輸出函數 • 範例 CH10_08.c
10-1 有緩衝區的輸入與輸出函數 • 執行結果 • 程式解說 • 第9~10行分別開啟要讀取與寫入的兩個檔案。 • 第12行檢查檔案是否開啟成功。 • 第15行使用while迴圈判斷檔案fptr是否讀取完畢。 • 第17行str[31]是用來儲存‘\0’。 • 第19行將str字串寫入到fptr1檔案中。
10-1 有緩衝區的輸入與輸出函數 • fprintf()函數 • 寫入檔案的fprintf()函數,與printf()函數不同在於printf()輸出到螢幕上,fprintf()可指定到特定的資料流物件。指令如下: • 參數說明 • stream: 指定資料流物件指標。 • format:格式化的字串,同printf()函數設定。 • 例如: intfprintf ( FILE * stream, const char * format, ... ); File *fptr; int math,eng; float average; fprintf(fptr, "%d\t%d\t%f\n",math,enf,average);
10-1 有緩衝區的輸入與輸出函數 • 範例 CH10_09.c
10-1 有緩衝區的輸入與輸出函數 • 執行結果 • 程式解說 • 第6行宣告一個指標形態的變數,變數名稱pFile。 • 第8行宣告存放字串的字元陣列。 • 第10行寫入方式開啟檔案。 • 第15行以gets()函數輸入字串。利用格式化寫入函數fprint()將字串資料寫入檔案。
10-1 有緩衝區的輸入與輸出函數 • fscanf()函數 • fscanf()函數與scanf()函數相當類似,只是scanf()函數是由使用者的鍵盤輸入取得資料,而fscanf()函數則由檔案中讀取所指定的資料。也就是由資料流讀取資料。並設定參數代號,可透過此函數,反向的將資料參考(reference)到指定的變數中。指令如下: intfscanf ( FILE * stream, const char * format, ... );
10-1 有緩衝區的輸入與輸出函數 • fprintf()函數與fscanf()函數 • 參數說明 • stream: 指定資料流物件指標。 • format:格式化的字串。如下所示
10-1 有緩衝區的輸入與輸出函數 • 範例 CH10_10.c
10-1 有緩衝區的輸入與輸出函數 • 執行結果 • 程式解說 • 第6行宣告一個指標形態的變數,變數名稱pFile。 • 第9行以可讀取或寫入方式開啟檔案。 • 第13行以fprintf()函數寫入資料。 • 第15行以scanf()函數讀取資料。
10-1 有緩衝區的輸入與輸出函數 • fwrite()函數 • 當在使用fwrite()函數時,就可將變數、陣列或是結構的記憶體位址傳送給它。指令如下: • 參數說明 • p:資料區塊的指標。 • s:每個元素的資料大小。 • c:總資料數量。 • stream: 指定資料流物件指標。 • 例如: size_tfwrite ( const void * p, size_t s, size_t c, FILE * stream ); File *fptr; char str[20]; int count; fwrite(str,sizeof(char),count,fptr);
10-1 有緩衝區的輸入與輸出函數 • 範例 CH10_11.c
10-1 有緩衝區的輸入與輸出函數 • 執行結果 • 程式解說 • 第6行宣告一個指標形態的變數,變數名稱pFile。 • 第9行以寫入方式開啟檔案。 • 第12行利用gets()函數取得使用者輸入的資料。 • 第13行利用fwrite()函數以區塊方式寫入資料。
10-1 有緩衝區的輸入與輸出函數 • fread()函數 • 如果想要讀取fwrite()函數所寫入的資料內容,就必須採取fread()函數來讀取檔案,才可以正確讀出有意義的資訊。指令如下: • 參數說明 • p:資料區塊的指標。 • s:每個元素的資料大小。 • c:總資料數量。 • stream: 指定資料流物件指標。 size_tfread ( void * p, size_t s, size_t c, FILE * stream );
10-1 有緩衝區的輸入與輸出函數 • 範例CH10_12.c
10-1 有緩衝區的輸入與輸出函數 • 範例CH10_12.c
10-1 有緩衝區的輸入與輸出函數 • 執行結果 • 程式解說 • 第6行宣告一個字元型態的指標變數。 • 第7行宣告固定長度的字元陣列。 • 第15行以fread()函數回傳值表示讀取資料的長度。 • 第16行在字串陣列中加入NULL的字元表示結束。 • 第24行以fread()函數讀取資料流時,直接指定字元型態指標,以存放讀入的資料。
10-1 有緩衝區的輸入與輸出函數 • fseek函數與rewind()函數 • 當每次使用檔案存取函數一次,檔案讀取游標都會往下一個位置移動。 • 例如像fgetc()函數讀取完畢後會移動一個位元組,而在fgets()函數中,由於我們的lentgh長度為10,所以它一次會讀取9個位元組的長度(因為最後一個位元組必須填入'\0'),像這種讀取方式,可稱之為循序式讀取。其實檔案中也可以藉由fseek()函數來操作讀取游標。指令如下: intfseek ( FILE * stream, long intos, int o );
10-1 有緩衝區的輸入與輸出函數 • fseek函數與rewind()函數 • 參數說明 • stream: 指定資料流物件指標。 • os:位移量。 • o:開始的位置。所謂位移量,單位是位元組,由游標起始點向前或向後的位移量。而起點參數則是游標起始點設定位移量的計算起點。共有3種巨集常數,說明如下:
10-1 有緩衝區的輸入與輸出函數 • fseek函數與rewind()函數 • 例如: File *fptr; fseek(fptr,10,SEEK_SET); /* 從檔案開頭向後計算10個位元組 */ fseek(fptr,10,SEEK_CUR); /* 目前的游標位置向後計算10個位元組 */ fseek(fptr,10,SEEK_END); /* 從檔案尾端向前計算10個位元組 */
10-1 有緩衝區的輸入與輸出函數 • 範例CH10_13.c
10-1 有緩衝區的輸入與輸出函數 • 範例CH10_13.c
10-1 有緩衝區的輸入與輸出函數 • 執行結果 • 程式解說 • 第10~14行建立A~Z的資料於fileIO.txt檔案中。 • 第21~25行利用for迴圈,共執行五次。 • 第24行利用fseek()函數,每次跳躍3個間格。
10-1 有緩衝區的輸入與輸出函數 • 範例CH10_14.c
10-1 有緩衝區的輸入與輸出函數 • 範例CH10_14.c