C語言----檔案(高階篇二十八)
檔案指標
定義:
FILE *指標變數名;
如:
FILE *fp1,*fp2;
一次定義了兩個指向檔案的指標
檔案操作方式
※文字方式
文字方式將資料以ASCII碼方式儲存在檔案中,我們電腦中的“文字檔案”就是典型的以文字方式儲存的檔案。
※二進位制方式
音樂、圖形這類非文字資料,就比較適合使用二進位制方式儲存
開啟檔案
格式:
FILE *fopen(檔名,檔案使用方式);
如:
FILE *fp;
fp=fopen(“file_a”,”r”);
使用方式列表:
※ ”r”,文字只讀
※ ”rb”,二進位制只讀
※ ”w”,文字只寫
※ ”wb”,二進位制只寫
※ ”a”,文字新增
※ ”ab”,二進位制新增
※ r+,w+,a+,rb+,wb+,ab+
帶加號方式開啟的檔案,讀寫都允許,其它操作與前面6項一樣。
開啟檔案經常會出現錯誤,比如這個檔案根本就不存在。可用以下方法檢查:
if((fp=fopen(“file_a”,”r”))= =NULL)
{
printf(“Cannot open this file\n”);
exit(0); /*使程式退出執行*/
}
關閉檔案
格式:
fclose(檔案指標);
文字檔案的讀寫
寫入:
putc(字元,檔案指標);
讀取:
char getc(檔案指標);
判斷是否檔案尾部:
EOF
因為ASCII字元沒有負數,所以在C語言中將EOF定義為-1。用檔案讀取函式時,遇見-1或EOF即為檔案結束標誌。
程式1
將字串”Hello”寫入文字檔案
// 28-1將字串hello寫入文字檔案.c #include <stdio.h> main() { FILE*fp; //定義檔案指標 char str[20] = "hello"; //定義寫入的字串 char *pc = str; //指向字元名指標 fp = fopen("myfile.txt", "a"); //開啟檔案 if (fp == NULL) //如果是 fp為空 { printf("開啟檔案錯誤!\n"); exit(0); //系統退出 } while (*pc != '\0') { putc(*pc, fp); //寫入字元到檔案 pc++; } fclose(fp); //關閉檔案 }
程式2
讀取程式1中文字檔案的內容
// 28-2讀取myfile中文字檔案的內容.c #include <stdio.h> main() { FILE *fp; //定義檔案指標 char str[20]; //定義一個字元,接收檔案中的字元 char *pc = str; //指標指向字元名 fp = fopen("myfile.txt", "r"); //讀取myfile檔案 if (fp == NULL) { printf("開啟檔案失敗!"); exit(0); } //迴圈讀取檔案中的字元,直到讀取到 EOF結束 *pc = getc(fp); //這一句是為了下面while迴圈的時候判斷是否是EOF while (*pc != EOF) { pc++; *pc = getc(fp); } *pc = '\0'; //賦值結尾符 fclose(fp); printf("%s\n", str); }
除這兩個函式外,還有幾個可以批量讀取資料的函式:
fscanf(檔案指標,格式控制字串,輸出表列);
如:
fscanf(fp,”%d %d”,&a,&b);
fprintf(檔案指標, 格式控制字串,輸出表列);
如:
fprintf(fp,”%d %d”,a,b);
fgets(陣列名,字元個數,檔案指標);
如:
fgets(str,n,fp);
fputs(陣列名,檔案指標);
如:
fputs(str,fp);
※這幾個函式有點類似我們平時操作字串時候用到的函式,只是fgets加了個“字元個數”引數。
二進位制檔案的讀寫
二進位制檔案可以儲存任何型別的資料,就有可能出現負數,因此在判斷檔案尾部時得改用其它方法。
判斷檔案尾部函式:
int feof(檔案指標);
遇到檔案結束,返回值為1,否則為0。
寫入:
fwrite(記憶體首地址,記憶體大小,記憶體個數,檔案指標);
讀取:
fread(記憶體首地址,記憶體大小,記憶體個數,檔案指標);
程式3
讀寫二進位制檔案
// 28-3讀寫二進位制檔案.c #include <stdio.h> #include <string.h> //定義學生結構 struct student { char name[10]; //名字 int age; //年齡 }; main() { FILE *fp; struct student stu1, stu2; //定義兩個學生結構變數 stu1.age = 17; //學生1年齡賦值 strcpy(stu1.name, "張三瘤子"); //字串賦值需要用函式賦值 //將結構變數寫入檔案 fp = fopen("temp.dat", "wb"); //fwrite(記憶體首地址,記憶體大小,記憶體個數,檔案指標); fwrite(&stu1, sizeof(struct student), 1, fp); fclose(fp); //讀取檔案到stu2 fp = fopen("temp.dat", "rb"); //fwrite(記憶體首地址,記憶體大小,記憶體個數,檔案指標); fread(&stu2, sizeof(struct student), 1, fp); fclose(fp); printf("%s\n%d\n", stu2.name, stu2.age); }
// 28-4二進位制檔案與文字檔案的區別.c // #include <stdio.h> main() { FILE *fp; int i = 7000; //二進位制檔案 /* fp = fopen("temp.txt", "wb"); //用二進位制開啟建立的檔案是亂碼 fwrite(&i, sizeof(int), 1, fp); */ //文字檔案 fp = fopen("temp1.txt", "w"); fprintf(fp,"%d",i); fclose(fp); }
練習
請呼叫fputs函式,把5個字串輸出到檔案中(注意每個字串用回車分開);再從此檔案中讀入這5個字串放在一個字串陣列中;最後把字串陣列中的字串輸出到終端螢幕,以檢驗所有操作是否正確。
/*28-5 練習.c 請呼叫fputs函式,把5個字串輸出到檔案中(注意每個字元用回車分開); 再從此檔案中讀入這5個字串放在一個字串陣列中;最後把字串陣列中的 字串輸出到終端螢幕,以檢驗所有操作是否正確。 */ #include <stdio.h> main() { char strout[5][10] = { "shout","anything","tent","mouse","ear" }; //寫入的檔案 char strin[5][10]; FILE *fp; //寫入檔案 if ((fp = fopen("28.txt", "w")) == NULL) { printf("檔案開啟錯誤!"); exit(0); } for (int i = 0; i < 5; i++) { fputs(strout[i],fp); putc('\n',fp); } fclose(fp); //讀取檔案 if ((fp = fopen("28.txt","r")) == NULL) { printf("檔案開啟錯誤!"); exit(0); } for (int i = 0; i < 5; i++) { //fscanf(檔案指標, 格式控制字串, 輸出表列); fscanf(fp,"%s",strin[i]); printf("%s\n", strin[i]); } }