C語言中對文件進行操作必須首先打開文件,打開文件主要涉及到fopen函數。fopen函數的原型為
FILE* fopen(const char *path,const char *mode)
其中path為文件路徑,mode為打開方式
1)對於文件路徑,只需注意若未明確給出絕對路徑,則默認該文件在工程的目錄下。若需給出絕對路徑,則注意轉義字符'\',比如有文件test.txt存放在C盤根目錄下,則文件路徑參數值應為C:\\test.txt。
2)對於mode,主要由r,w,a,+,b,t六個字符組合而成。
r:只讀方式,文件必須存在
w:只寫方式,若文件存在,則原有內容會被清除;若文件不存在,則會建立文件
a:追加方式打開只寫文件,只允許進行寫操作,若文件存在,則添加的內容放在文件末尾;若不存在,則建立文件
+:可讀可寫
b:以二進制方式打開文件
t:以文本方式打開文件(默認方式下以文本方式打開文件)
下面是常見的組合:
r: 以只讀的方式打開文件,只允許讀,此文件必須存在,否則返回NULL,打開成功返回的指針指向文件頭部
r+: 以可讀可寫的方式打開文件,允許讀寫,此文件必須存在,否則返回NULL,打開成功返回的指針指向文件頭部
rb+: 以可讀可寫、二進制方式打開文件,允許讀寫,此文件必須存在,否則返回NULL,打開成功返回的指針指向文件頭部
rt+: 以可讀可寫、二進制方式打開文件,允許讀寫,此文件必須存在,否則返回NULL,打開成功返回的指針指向文件頭部
w: 以只寫的方式打開文件,只允許寫,若文件存在,文件中原有內容會被清除;若文件不存在,則創建文件,打開成功返回的指針 指向文件頭部
w+: 以讀寫的方式打開文件,允許讀寫,若文件存在,文件中原有內容會被清除;若文件不存在,則創建文件,打開成功返回的指針 指向文件頭部
a: 以追加、只寫的方式打開文件,只允許寫。若文件存在,則追加的內容添加在文件末尾,若文件不存在,則創建文件。打開成功返回的指針指向文件頭部(注意很多書上或資料上講述追加方式打開成功後指針指向文件末尾是錯誤的)
a+: 以追加、可讀寫的方式打開文件,允許讀寫。若進行讀操作,則從頭開始讀;若進行寫操作,則將內容添加在末尾。若文件不存在,則創建文件。打開成功返回的指針指向文件頭部
其他方式類似。
下面討論一下以二進制方式和文本方式打開文件有什麼區別。
其實這兩種方式打開文件並沒有太大的區別,僅僅只有一點區別就是在處理某些特殊字符的時候。
以文本方式打開文件,若將數據寫入文件,如果遇到換行符'\n'(ASII 值為10,0A),則會轉換為回車—換行'\r\n'(ASII值為13,10,0D0A)存入到文件中,同樣讀取的時候,若遇到回車—換行,即連續的ASII值13,10,則自動轉換為換行符。
而以二進制方式打開文件時,不會進行這樣的處理。以上所述只在windows下存在,在unix下沒有區別。
1.測試程序—檢測以追加的方式打開文件時,指針的初始位置
假設工程目錄下已存在文件test.txt,文件中含有的字符串為"ABC"
/*測試fopen函數以追加方式打開文件時初始指針的位置 2011.10.5*/ #include<stdio.h> #include<stdlib.h> int main(void) { int n; FILE *fp; if((fp=fopen("test.txt","a"))==NULL) { printf("can not open file\n"); exit(0); } n=ftell(fp); //得到此時fp所處位置距文件首的偏移字節數 printf("%d\n",n); fputs("test",fp); n=ftell(fp); printf("%d\n",n); fclose(fp); return 0; }
輸出結果為:
0
7
Press any key to continue
由輸出結果可知,初始打開文件後,指針是位於文件首部,只是在往文件中添加內容時,才將文件指針移動到文件末尾。
2.測試程序—檢測以二進制方式和文本方式打開文件的區別
/*測試以二進制方式和文本方式打開文件的區別 2011.10.5*/ #include<stdio.h> #include<stdlib.h> int main(void) { char ch; int i; char s[]={'A','B','\n','C'}; FILE *fp1,*fp2; if((fp1=fopen("test1.txt","wt"))==NULL) { printf("can not open file\n"); exit(0); } if((fp2=fopen("test2.txt","wb"))==NULL) { printf("can not open file\n"); exit(0); } for(i=0;i<4;i++) { fputc(s[i],fp1); //以文本方式向文件中寫入數據 fputc(s[i],fp2); //以二進制方式向文件中寫入數據 } fclose(fp1); fclose(fp2); if((fp1=fopen("test1.txt","rt"))==NULL) { printf("can not open file\n"); exit(0); } if((fp2=fopen("test1.txt","rb"))==NULL) { printf("can not open file\n"); exit(0); } ch=fgetc(fp1); while(!feof(fp1)) //以文本方式從文件中讀取數據 { printf("%02X",ch); ch=fgetc(fp1); } printf("\n"); ch=fgetc(fp2); while(!feof(fp2)) //以二進制方式從文件中讀取數據 { printf("%02X",ch); ch=fgetc(fp2); } printf("\n"); fclose(fp1); fclose(fp2); return 0; }
在向文件中寫完數據後,用UltraEdit以二進制方式打開test1.txt和test2.txt,看到的結果如下:
根據得到的結果可知,以文本方式寫入時,多寫入了一個字符0D,即'\r'。
程序輸出結果:
41420A43
41420D0A43
請按任意鍵繼續. . .
分別以文本方式和二進制方式讀取test1.txt時,輸出的內容不同。
可知在以文本方式讀取時,對'\r\n'進行了轉換,而二進制方式讀取時卻沒有進行這樣的轉換
作者 海子