File(檔案處理) 學習目標:開檔、讀檔、更新檔與關閉檔案
大綱 檔案的觀念 檔案的處理方式 檔案的函數使用:fopen …
檔案的觀念 檔案儲存的方式可以分為兩種: 文字檔 以ASCII碼儲存,每個字元皆佔有1個位元組。 若將數值182956存在文字檔中,會當成6個字元來存檔 49 56 50 57 53 54 以 ASCII 碼儲存 二進位檔 以二進位的格式儲存,如影像檔或執行檔。 將整數182956以二進位的格式來存檔時,會以其二進位的值來儲存 101100101010101100
檔案的處理方式 程式在執行的時候,會需要一些額外的記憶體來存放資料,以提高程式執行的效率,此暫時存放的區域就稱為緩衝區(buffer)。 有緩衝區: fopen("檔名", "存取模式"); 無緩衝區 open("檔名",開啟模式,存取屬性);
fopen函數 在使用檔案之前,必須先開啟檔案。 可利用標準輸入/輸出(standard I/O)函數 fopen 來開啟檔案。 範例: fopen 函數會回傳一個 FILE 指標 範例: FILE *fp; 必須宣告一個指向檔案的指標 fp = fopen("phone" , "r"); 將 fp 指標指向 phone 檔案 利用fopen函數開啟檔案時,若開啟失敗,會回傳 NULL
fopen函數 檔案的存取模式如下表: 代碼 說明 r w a 存取模式 開啟檔案以供讀取。 讀取資料 檔案必須存在,否則會開啟失敗。 寫入資料 w 開啟檔案以供寫入。 原有檔案若存在,則內容會被覆蓋掉。 若檔案不存在,則系統會自動產生此檔案。 附加於檔案之後 a 開啟一個檔案,可將資料寫入此檔案的末端。 若檔案不存在,系統會自動產生。
開檔範例 #include<stdio.h> void main() { FILE *fp ; /*宣告指向檔案的指標fp*/ fp = fopen ("C:\\abc.txt " , "r" ) ; if (fp = = NULL) /*判斷開檔是否成功*/ printf("檔案開啟失敗\n"); else printf("檔案開啟成功\n"); system("pause"); } 由於反斜線是C語言中的控制字元,因此必須 將路徑中有反斜線(\)的部分再加一個反斜線。
存取檔案的常用函數(1) 函數功能 格式與說明 開啟檔案 fopen()傳回值為檔案指標或NULL(開檔失敗)。 關閉檔案 int fclose(FILE *fptr);關閉由fptr指向的檔案。 讀取字元 int getc(FILE *fptr);由fptr所指向的檔案一次讀取一個字元,傳回值字元。若遇到檔案結尾,會傳回EOF。 寫入字元 int putc(int ch, FILE *fptr);將字元 ch寫入由fptr所指向的檔案。
讀檔範例 #include<stdio.h> void main() { FILE *fptr; char ch; int count=0; fptr = fopen("c:\\test.txt" , "r"); if( fptr != NULL) /*開檔成功*/ while((ch = getc(fptr)) !=EOF ) /*判斷是否到達檔尾*/ printf("%c",ch); count++; //一次印出一個字元 } fclose(fptr); //關閉檔案 printf("\n 共有 %d 字元\n",count); else printf("檔案開啟失敗!! "); system("pause"); /*ch是用來接收讀取的字元*/ /*count用來計算檔案的字元數*/
存取檔案的常用函數(2) 函數功能 格式與說明 寫入字元 int fputc(int ch, FILE *fptr); fputc()函數返回一個向檔案所寫字元的值,此時寫操作成功,否則返回EOF(文件結束結束其值為-1,在stdio.h中定義)表示寫操作錯誤。 寫入字串 int fputs(const char *str, FILE *fptr); 將字串 str 寫入 fptr 所指向的檔案。 寫入檔案 int fprintf(FILE *fptr, char *format, <variable-list>); 將資料以規定格式寫入檔案內 Ex: fprintf(fp,"\2: The average is %6.2f",average); 檢查檔案是否結束 int feof(FILE *fptr); 檢查fptr所指向的檔案是否已讀取到檔案結束的位置。 若尚未到達檔尾,則傳回0。
存取檔案的常用函數(3) 函數功能 格式與說明 讀取字元 int fgetc(FILE *fptr); 讀取字串 fgetc()函數返回檔案目前位置的一個字元,讀取錯誤時傳回EOF。 讀取字串 char *fgets(char *str, int maxchar, FILE *fptr); 第一個參數:字元陣列名稱 第二個參數:陣列大小 第三個參數:指向檔案的指標 讀取檔案 int fscanf(FILE *fptr, char *format, <address-list>); fscanf()函數的用法與scanf()函數相似,只是它是從文件中讀到資訊。 fscanf()函數的返回值為EOF(即-1),表明讀取資料錯誤。
寫檔範例 #include<stdio.h> void main() { FILE *fp; int c; fp = fopen("c:\\hello.txt","w"); while((c=getchar())!=EOF) fputc(c , fp); /*將字元c輸出到fp所指的檔案*/ fclose(fp); } /*判斷是否已輸入完畢*/
將檔案的內容列於螢幕 #include<stdio.h> void main() { int c, r; char filename[20]; FILE *fp; printf("please input a filename:"); scanf("%s",filename); if( (fp=fopen(filename, "r"))==NULL) /*判斷開檔是否成功*/ printf("Cannot open the file!!\n"); else while((c=fgetc(fp))!=EOF) /*判斷是否到達檔尾*/ putchar(c); /*將字元c列於螢幕上*/ if((r=fclose(fp))!=0) /*判斷關檔是否成功*/ printf("Cannot close file!\n"); } system("pause");
fgets函數應用 #include<stdio.h> void main() { int r , MAX=80; char str[MAX],*msg; FILE *fptr=fopen("C:\\output.txt","r"); if(fptr==NULL) printf("檔案開啟失敗\n"); else while(!feof(fptr)) msg=fgets(str,MAX,fptr); printf("%s",msg); } if((r = fclose(fptr))!=0) printf("Cannot close file!\n"); } system("pause");
存取檔案的常用函數(4) 函數功能 格式與說明 隨機讀取 int fread(void *buf, int size, int count, FILE *fptr); fread()函數是從檔案中讀count個欄位, 每個欄位長度為size個位元群組, 並把它們存放到buf指標所指的緩衝器中。 隨機寫入 int fwrite(void *buf, int size, int count, FILE *fptr); fwrite()函數是把buf指標所指的緩衝器中, 長度為size個位元群組的count個字段寫到fptr指向的檔案中去。 指定文件位置 int fseek (FILE *fptr, long offset, int fromwhere); fseek()函數的作用是將檔案的位置指標設定到從fromwhere開始的第offset位元群組的位置上 文件位置指標起始計算位置fromwher: SEEK_SET 0 從檔案開頭 SEEK_CUR 1 從檔案指標的現行位置 SEEK_END 2 從檔案末尾
Water Restrictions to Return to Taoyuan Area 練習 將以下這篇英文文章的字母全部改成小寫字母。 Water Restrictions to Return to Taoyuan Area WATER RESTRICTIONS ARE RETURNING TO THE TAOYUAN AREA. WATER OFFICIALS SAY STARTING NEXT WEEK... THEY WILL START REMOVING MUD AND SEDIMENT FROM THE SHI-MEN RESERVOIR. THE CLEAN UP OPERATIONS WILL INCREASE THE WATER'S TURBIDITY, AND THEREBY DECREASE OUTPUT FROM A NEARBY WATER PURIFICATION PLANT. TO MAKE THE WATER RESTRICTIONS MORE FAIR, THEY WILL IMPOSED ON A ROTATING BASIS. OVER THE PAST FOUR DECADES... NEARLY 56-MILLION CUBIC METERS OF SEDIMENT HAVE ACCUMULATED IN THE RESERVOIR... WITH NEARLY 35-PERCENT OF THAT TOTAL FROM TYPHOON AERE ALONE.