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,則自動轉換為換行符。

而以二進制方式打開文件時,不會進行這樣的處理。

還有如果以文本方式打開文件時,若讀取到ASCII碼為26(^Z)的字符,則停止對文件的讀取,會默認為文件已結束,而以二進制方式讀取時不會發生這樣

的情況。由于正常情況下我們手動編輯完成的文件是不可能出現ASCII碼為26的字符,所以可以用feof函數去檢測文件是否結束。以上所述的兩點區別只

在windows下存在,在unix下沒有區別。

注意:1)在以追加方式打開文件時,位置指針指向文件的首部。

在這里區分一下位置指針和文件指針:

文件指針:指向存儲文件信息的一個結構體的指針

位置指針:對文件進行讀寫操作時移動的指針

在頭文件中存在一個結構體_iobuf,在VC6.0中選中FILE,然后F12,則可以看到_iobuf的具體定義:

struct_iobuf {

char*_ptr;

int_cnt;

char*_base;

int_flag;

int_file;

int_charbuf;

int_bufsiz;

char*_tmpfname;

};

typedefstruct_iobuf FILE;

比如用FILE *fp定義了一個文件指針,并成功打開一個文件之后,fp只是指向該結構體,而在對文件進行讀寫操作時,fp的值并不會改變,改變的是結構體中_ptr的值,這個_ptr就是位置指針。

2)以追加方式打開時,若進行寫操作,則rewind函數和fseek函數不會起到作用,因為以追加方式打開時進行寫操作的話,系統會自動將位置指針移動到末尾。

3)當文件打開用于更新時,可以通過文件指針對文件進行讀寫操作,但是如果沒有給出fseek或者rewind的話,讀操作后面不能直接跟寫操作,否則會是無效的寫操作(位置指針會移動,但是需要寫入文件的內容不會被寫入到文件當中),但是寫操作后可以直接跟讀操作。

1.測試程序

假設工程目錄下已存在文件test.txt,文件中含有的字符串為"ABC"

/*測試fopen函數以追加方式打開文件時初始指針的位置 2011.10.5*/

#include

#include

intmain(void)

{

intn;

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);

return0;

}

輸出結果為:

0

7

Press any key to continue

由輸出結果可知,初始打開文件后,指針是位于文件首部,只是在往文件中添加內容時,才將文件指針移動到文件末尾。

2.測試程序

/*測試以二進制方式和文本方式打開文件的區別 2011.10.5*/

#include

#include

intmain(void)

{

charch;

inti;

chars[]={'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);

return0;

}

在向文件中寫完數據后,用UltraEdit以二進制方式打開test1.txt和test2.txt,看到的結果如下:

根據得到的結果可知,以文本方式寫入時,多寫入了一個字符0D,即'\\r'。

程序輸出結果:

41420A43

41420D0A43

請按任意鍵繼續. . .

分別以文本方式和二進制方式讀取test1.txt時,輸出的內容不同。

可知在以文本方式讀取時,對'\\r\\n'進行了轉換,而二進制方式讀取時卻沒有進行這樣的轉換(要注意,windows和linux下的換行符是不一樣的,在windows下換行符是\\r\\n,即0X0D、0X0A,而在linux下換行符是\\n,即0X0A。

3.測試程序

/*測試讀操作后能否直接跟寫操作 2011.10.5*/

#include

#include

intmain(void)

{

intch;

intn;

FILE *fp;

if((fp=fopen("test.txt","r+"))==NULL)

{

printf("can not open file\\n");

exit(0);

}

fseek(fp,1L,0);//將fp移動到距文件首1字節的位置

ch=fgetc(fp);

printf("%c\\n",ch);

//rewind(fp);

fseek(fp,1L,0);

fputs("test",fp);

ch=fgetc(fp);

printf("%c\\n",ch);

fclose(fp);

return0;

}

假設工程已經存在文件test.txt,文件中含有字符串"ABCDEFGH"。

則上述程序執行結果為:

B

F

請按任意鍵繼續. . .文件中內容為"AtestFGH"。

與預想結果相同,因此讀取到字符'B'后,再將位置指針置到距文件首1字節處,即字符'B'處,寫入"test"后,會覆蓋掉"BCDE",寫完后位置指針指向字符'F',因此此時進行讀操作,得到的結果是'F'。

但是如果將fseek(fp,1L,0);這句注釋掉,則執行結果為:

B

G

請按任意鍵繼續. . .

文件中的內容為"ABCDEFGH"。

注釋掉fseek一句后,讀取完字符'B'后,位置指針指向字符'C',再進行寫操作,位置指針會向后移動4個字節的位置,指向字符'G',因此第二次讀取的輸出結果為'G'。但是文件中的內容沒有被改寫,相當于這次寫操作是無效操作。

4.測試程序

#include

#include

intmain(void)

{

FILE *fp;

intch;

if((fp=fopen("test","rb"))==NULL)

{

printf("can not open file\\n");

exit(0);

}

ch=fgetc(fp);

while(feof(fp)==0)

{

printf("%02X\\n",ch);

ch=fgetc(fp);

}

fclose(fp);

return0;

}

運行此程序之前,用VC6.0建立一個二進制文件test放在工程目錄下,然后輸入數據"23 13 0E 1A 35"。保存完畢后再執行此程序,執行結果為:

23

13

0E

1A

35

Press any key to continue

但是若將打開方式改成"rt",則執行結果為:

23

13

0E

Press any key to continue

之所以出現這種原因,在上面已經提到,就是在以文本方式打開文件時,若讀取到ASCII碼為26的字符,則會停止讀取,默認文件內容已經結束。但是以二進制方式打開文件則不會出現這種情況,會將文件中所有的內容原樣輸出(注意這種區別只在windows下存在,在unix下兩種方式打開文件程序的執行結果是相同的即會原樣輸出文件中所有的內容)。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內容