1 / 33

12/23 計程實習課

12/23 計程實習課. Speaker: Wen-Ching Lo Date: 2009/12/23. Outline. 檔案的輸入與輸出 Structure. 檔案的輸入與輸出. C 軟體提供了許多檔案的輸入與輸出函數,這些函數可分成兩大類。 有緩衝區的輸入與輸出 (Buffered I/O) 無緩衝區的輸入與輸出 (Unbuffered file I/O) 有緩衝區的輸入與輸出,是當它在讀取檔案資料或將資料寫入檔案時,一定都先經過一個緩衝區。 沒有緩衝區的輸入與輸出,表示輸入與輸出的動作,是直接在磁碟內執行讀取資料和寫入資料的動作。

Download Presentation

12/23 計程實習課

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 12/23計程實習課 Speaker: Wen-Ching Lo Date: 2009/12/23

  2. Outline • 檔案的輸入與輸出 • Structure

  3. 檔案的輸入與輸出 • C軟體提供了許多檔案的輸入與輸出函數,這些函數可分成兩大類。 • 有緩衝區的輸入與輸出(Buffered I/O) • 無緩衝區的輸入與輸出(Unbuffered file I/O) • 有緩衝區的輸入與輸出,是當它在讀取檔案資料或將資料寫入檔案時,一定都先經過一個緩衝區。 • 沒有緩衝區的輸入與輸出,表示輸入與輸出的動作,是直接在磁碟內執行讀取資料和寫入資料的動作。 • 由於有緩衝區的輸入與輸出函數是包含在stdio.h檔案內,所以程式前面,必須要包含下列指令。 # include <stdio.h >

  4. fopen( ) • fopen( )函數主要是用於開啟檔案。檔案在磁碟裡,使用前是需先經過開啟動作的。使用格式如下: FILE *fopen(char *filename, char *mode); • filename:檔案指標,指的是欲開啟的檔案名稱。 • mode:檔案使用模式,指的是檔案被開啟之後,它的使用方式。 • “r”:開啟一個文字檔(text),供程式讀取。 • “w”:開啟一個文字檔,供程式將資料寫入此檔案內。如果磁碟內不包含這個檔案,則系統會自行建立這個檔案。如果磁碟內包含這個檔案,則此檔案內容會被蓋過而消失。 • “a”:開啟一個文字檔,供程式將資料寫入此檔案的末端。如果此檔案不存在,則系統會自行建立此檔案。

  5. fopen( ) • “rb”:開啟一個二元檔(binary),供程式讀取。 • “wb”:開啟一個二元檔,供程式資料寫入此檔案內。如果磁碟內不包含這個檔案,則系統會自行建立這個檔案。如果磁碟內包含這個檔案,則此檔案內容會被蓋過而消失。 • “ab”:開啟一個二元檔,供程式將資料寫入此檔案末端,如果此檔案不存在,則系統會自行建立此檔案。 • 前述的fopen( )函數的使用格式是以指標方式設計,而經常也會直接以字串方式設計此函數: FILE *fopen(“filename”, “mode”);

  6. fclose( ) • fclose( )為關閉檔案的函數。C語言中關閉檔案主要有兩個目的: • 促使檔案在關閉前會將檔案緩衝區資料寫入磁碟檔案內,否則檔案緩衝區資料會遺失。 • 一個C語言程式,在同一時間可開啟的檔案數量有限,一般是20個,如果你的程式很大,要開啟超過20個檔案時,你必須將暫時不用的檔案關閉。 • fclose( )執行失敗,它的傳回值是非零值,如果fclose()執行成功,它的傳回值是零。 使用格式: int fclose(FILE *fname);

  7. fputc( ) • putc( )函數的主要功能是將一個字元,寫入某檔案內,它的使用格式如下: int putc(int ch,FILE * fp); • ch代表所欲輸出的字元。 • fp檔案指標。 • 此函數如果執行成功,它的傳回值是ch字元值。如果執行失敗,它的傳回值是EOF。

  8. getc( ) • getc( )函數的主要目的是從某一個檔案中,讀取一個字元,它的使用格式如下: int getc(FILE *fp); • 當執行getc( )函數成功時,傳回值是所讀取的字元,如果所讀取的是檔案結束字元,則此值是EOF。而在stdio.h內,EOF值是 -1。

  9. 範例1(計算此程式的字元數量) #include <stdio.h> int main() { FILE *fp; int count = 0; fp = fopen("13_1.c","r"); if(fp == NULL) { printf("\n******open file error*****"); exit(1); } while ( getc(fp) != EOF ) count++; printf("The number of character for 13_1.c is %d\n", count); fclose(fp); return 0; }

  10. int main( intargc, char *argv[]) • C/C++語言中的main函數,經常帶有參數argc,argv,如下: • int main( int argc, char *argv[]) • argc 是指命令行輸入參數的個數。 • argv是儲存了所有的命令行參數。

  11. 範例2(複製檔案到另一檔案) #include <stdio.h> int main( int argc, char *argv[]) { FILE *fp1, *fp2; char chr; if(argc != 3) { printf("\ninput data error"); exit(1); } fp1 = fopen( argv[1], "r"); fp2 = fopen( argv[2], "w"); while ( (chr = getc(fp1) ) != EOF ) fputc (chr, fp2 ) ; fclose(fp1); fclose(fp2); return 0; }

  12. fprintf( ) • fprintf( )主要目的是供你將資料,以格式化方式寫入某檔案內 • fprintf(fp, “資料變數型態”,資料變數名稱 ); • 此函數格式和printf( )使用格式相同. • 兩者唯一的差別是,printf( )會將資料列印在螢幕上,而fprintf( )會將資料列印在某個檔案內。 Example: fprintf(fp,"%d\n",var); fprintf(fp,"\2: The average is %6.2f",average);

  13. fscanf() • fscanf( ) 主要的目的是讓我們從某個檔案讀取資料 • fscanf( fp , "……." , ………); • fscanf( )函數和scanf( )函數兩者之間最大的差別在,scanf( )函數主要用於從鍵盤輸入讀取資料,fscanf( )函數則是從fp檔案指標所指的檔案讀取資料。 Example: fscanf(fp,"%d",&var)

  14. feof( ) / ferror( ) • feof( )主要功能是測試在讀取資料時,是否已經讀到檔案末端位置: int feof(fp); • 若讀取資料的位置是在檔案末端,則傳回非零數值,否則傳回零。 • ferror( )主要用於測試前一個有關檔案指標的操作是否正確: int ferror(fp); • 如果前一個函數對有關檔案指標的操作,有錯誤,則傳回值是非零數值,否則傳回零值。

  15. fwrite( ) / fread( ) • fwrite( )主要目的是將某個資料緩衝區內容,寫入檔案指標所指的二元檔檔案內。 int fwrite(void *buffer, int num_byte, int count, FILE *ftp); • fread( )主要目的是將某二元檔檔案內的資料,讀入資料緩衝區內。 int fread(void *buffer, int num_byte, int count, FILE *fp);

  16. fseek( ) / rewind( ) • fseek( )主要目的是設定所要讀取資料的位置,以達隨機位置讀取檔案資料的目的。 int fseek(fp, long num_byte, int origin); • origin有三種格式: 0:表示從檔案開頭位置 1:表示從目前位置 2:表示從檔案末端位置 • num_byte為與origin的距離。 • rewind( ) 功能在於將檔案指標移至檔案的開頭。

  17. struct • 結構與陣列很類似,因為兩者都是將一些資料連接組合在一起,以下為兩者的比較。 • 陣列 : 相同型態資料之集合. • 結構(struct) :可將不同型態的資料組合在一起 • 結構(struct)為結構(structure)的縮寫 • 結構中的項目通常稱為成員(member)。

  18. Struct • 能夠結合多個彼此相關的變數在一個名稱之下,且可以包含數個不同資料型態的變數。 • 結構是一種使用者自定的型態,它可將不同的資料型態串在一起。 • 舉例:「學生個人資料表」, • 學號(字串型態) • 姓名(字串型態) • 成績(整數型態)

  19. Student • struct 結構名稱標籤 { 資料型態 變數1; 資料型態 變數2; ‧‧‧‧‧‧‧‧ }; • struct 結構名稱 變數1,變數2,…,變數m; • struct Student { char ID[10]; char FirstName[10]; char LastName[10]; int grade; }; • struct Student stu; ID[10] 98753506 FirstName[10] Wendy LastName[10] Lo grade 100

  20. ID LastName Student • 上頁敘述會在記憶體裡配置空間出來讓 student 結構變數使用,記憶體的配置情況如下: 記憶體 FirstName grade

  21. 將結構型態與結構變數的宣告寫在同一個敘述 struct 結構名稱 { 資料型態 欄位名稱1; 資料型態 欄位名稱2; . . 資料型態 欄位名稱n; }變數1,變數2,…,變數m;

  22. 利用小數點(.)來存取結構變數中的成員。 結構變數名稱.成員名稱 • 例如: • stu.ID = “96753017” • stu.Firstname= “Wendy” • stu.LastName = “Lo”; • stu.grade= 100;

  23. 初值的設定 • 範例 : struct Student /* 定義結構mydata */ { char ID[10]; char FirstName[10]; char LastName[10]; int grade; }; struct Student stu={“96753017”,”Wendy”,”Lo”,0 }; /* 宣告結構Student型態之變數stu,並設定結構內欄位的初值 */

  24. 結構陣列 結構變數亦可以用宣告陣列,語法如下: struct 結構名稱 結構陣列變數名稱[陣列大小]; • Ex: • struct Student • { • char ID[10]; • char FirstName[10]; • char LastName[10]; • int grade; • }; • struct Student stu[100];/*結構變數的宣告*/

  25. #include<stdio.h> #define MAX 2 int main(void) { int i; struct data /*定義結構data */ { char name[10]; int math; }student[MAX]; for(i=0;i<MAX;i++) /*宣告結構陣列student */ { printf("學生姓名:"); gets(student[i].name); printf("數學成績:"); scanf("%d",&student[i].math); fflush(stdin); /*清空緩衝區內的資料 */ } for(i=0;i<MAX;i++) /*輸出結構陣列的內容*/ printf("%s的數學成績=%d\n",student[i].name,student[i].math); system("pause"); return 0;}

  26. 結構指標 • 結構指標 結構變數也是指標的一種,只是它是指向結構的指標,而非指向一般變數。 宣告格式如下: struct 結構名稱 * 結構指標變數名稱; • Ex: • struct student /* 定義結構mydata */ • { • char name[15]; /* 各成員(欄位)的內容 */ • char id[10]; • int math; • int eng; • }; • struct student * prt; /*結構變數的宣告*/ • ptr=&student; /*將指標指向此結構變數 student*/

  27. 結構指標變數的使用 • 使用指標來存取結構變數內的成員(欄位)時,要利用「->」來連接欲存取的成員,如下面格式: 結構指標名稱 ->結構變數成員 Ex: 如前一頁所宣告的結構變數student及指標ptr為例, ptr->math即代表了指向結構變數student的math成員。

  28. #include<stdio.h> #include<stdlib.h> int main(void) { struct data { char name[10]; int eng; }student; struct data *ptr; ptr=&student; printf("學生姓名:"); gets(ptr->name); printf("英文成績: "); scanf("%d",&ptr->eng); printf("英文成績=%d",ptr->eng); system("pause"); return 0; }

  29. 巢狀結構 • 結構可以存放不同的資料型態,所以在結構中也可以擁有另一個結構,如此就稱為巢狀結構(nested structure). • 格式如下: struct 結構1 { /*結構1的成員*/ }; struct 結構2 { /*結構2的成員*/ struct 結構1 變數名稱; };

  30. #include<stdio.h> #include<stdlib.h> int main(void) { struct date /*define date*/ { int month; int day; }; struct student /*define nested structure---student*/ { char name[10]; int math; struct date birthday; }s1={“David Li",80, {2,10}}; printf("student name:%s\n",s1.name); printf("birthday:%d month, %d day\n",s1.birthday.month,s1.birthday.day); printf("math grade:%d\n",s1.math); return 0; }

  31. Merry Christmas

  32. 習題 • 題目:有一個表示學生國英數成績結構陣列如右所附。請完成二個函數,其原型分別為 void happy_birthday(struct data [], int); int max_grade(struct data []); 其功能可以(1)列印12月份生日的學生姓名; (2)傳回全班平均成績最高的學生的索引值 。 請完成函數,並依題目輸出要求,測試函數,印出結果。 題目輸入:八個學生資料如右所附。 題目輸出:(1)印出本月壽星的學生姓名 (2)印出全班平均成績最高的學生姓名 struct day{int yy, mm, dd; /* 年、月、日 */ };struct data{char name[20]; /* 姓名 */ struct day birthday; /* 生日 */ int chi, math, eng; /* 國文、數學 與 英文成績 */ }; struct data student[8] = {{"Marry Hu", {77, 2, 3}, 89, 90, 79}, {"Tom Chen", {78, 12, 13}, 79, 69, 88}, {"Billy Wu", {77, 1, 30}, 81, 54, 66}, {"John Hsu", {77, 7, 22}, 69, 49, 70}, {"Tim Huang", {77, 12, 8}, 90, 62, 83}, {"Marry Chen", {78, 5, 27}, 78,93, 91}, {"Tomas Chu", {77, 5, 18}, 80, 50, 68}, {"Ann Wang", {77, 9, 21},100,100, 100}};

More Related