函數簡介
函數功能:打開一個文件
函數原型:FILE * fopen(const char * path,const char * mode);
相關函數:open,fclose,fopen_s[1],_wfopen
所需庫:<stdio.h>
返回值:文件順利打開后,指向該流的文件指針就會被返回。如果文件打開失敗則返回NULL,并把錯誤代碼存在errno 中。
一般而言,打開文件后會做一些文件讀取或寫入的動作,若打開文件失敗,接下來的讀寫動作也無法順利進行,所以一般在fopen()后作錯誤判斷及處理。
參數說明:
參數path字符串包含欲打開的文件路徑及文件名,參數mode字符串則代表著流形態。
mode有下列幾種形態字符串:
r 以只讀方式打開文件,該文件必須存在。
r+ 以可讀寫方式打開文件,該文件必須存在。
rb+ 讀寫打開一個二進制文件,允許讀寫數據,文件必須存在。
rw+ 讀寫打開一個文本文件,允許讀和寫。
w 打開只寫文件,若文件存在則文件長度清為0,即該文件內容會消失。若文件不存在則建立該文件。
w+ 打開可讀寫文件,若文件存在則文件長度清為零,即該文件內容會消失。若文件不存在則建立該文件。
a 以附加的方式打開只寫文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數據會被加到文件尾,即文件原先的內容會被保留。(EOF符保留)
a+ 以附加方式打開可讀寫的文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數據會被加到文件尾后,即文件原先的內容會被保留。 (原來的EOF符不保留)
wb 只寫打開或新建一個二進制文件;只允許寫數據。
wb+ 讀寫打開或建立一個二進制文件,允許讀和寫。
ab+ 讀寫打開一個二進制文件,允許讀或在文件末追加數據。
at+ 打開一個叫string的文件,a表示append,就是說寫入處理的時候是接著原來文件已有內容寫入,不是從頭寫入覆蓋掉,t表示打開文件的類型是文本文件,+號表示對文件既可以讀也可以寫。
上述的形態字符串都可以再加一個b字符,如rb、w+b或ab+等組合,加入b 字符用來告訴函數庫以二進制模式打開文件。如果不加b,表示默認加了t,即rt,wt,其中t表示以文本模式打開文件。由fopen()所建立的新文件會具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)權限,此文件權限也會參考umask 值。
有些C編譯系統可能不完全提供所有這些功能,有的C版本不用"r+","w+","a+",而用"rw","wr","ar"等,讀者注意所用系統的規定。
二進制和文本模式的區別
1.在windows系統中,文本模式下,文件以"\r\n"代表換行。若以文本模式打開文件,并用fputs等函數寫入換行符"\n"時,函數會自動在"\n"前面加上"\r"。即實際寫入文件的是"\r\n" 。
2.在類Unix/Linux系統中文本模式下,文件以"\n"代表換行。所以Linux系統中在文本模式和二進制模式下并無區別。
打開方式總結:各種打開方式主要有三個方面的區別:
①打開是否為二進制文件,用“b”標識。
②讀寫的方式,有以下幾種:只讀、只寫、讀寫、追加只寫、追加讀寫這幾種方式。
③對文件是否必須存在、以及存在時是清空還是追加會有不同的響應。具體判斷如下圖。
程序示例
示例一
#include<stdio.h>
?
#defineF_PATH"d:\\myfile\\file.dat"
intmain(void)
{
FILE*fp=NULL;//需要注意
fp=fopen(F_PATH,"r");
if(NULL==fp)
{
return-1;//要返回錯誤代碼
}
fclose(fp);
fp=NULL;//需要指向空,否則會指向原打開文件地址
return0;
}
示例二
#include<stdio.h>
#include<stdlib.h>//為了使用exit()
intmain()
{
charch;
FILE*fp=NULL;
charfname[50];//用于存放文件名
printf("輸入文件名:");
scanf("%s",fname);
fp=fopen(fname,"r");//只供讀取
if(fp==NULL)//如果失敗了
{
printf("錯誤!");
exit(1);//中止程序
}
while((ch=getc(fp))!=EOF)
putchar(ch);
fclose(fp);//關閉文件
return0;
}
注意!初學者往往會犯一個錯誤,即在輸入文件名時不加后綴名,請注意加上!(為什么文件一定要有后綴名?)
示例三[2]
#include<stdio.h>
?
FILE*stream,*stream2;
?
intmain(void)
{
intnumclosed;
//Openforread(willfailiffile"crt_fopen.c"doesnotexist)
if((stream=fopen("crt_fopen.c","r"))==NULL)//C4996
//Note:fopenisdeprecated;considerusingfopen_sinstead
printf("Thefile'crt_fopen.c'wasnotopened\n");
else
printf("Thefile'crt_fopen.c'wasopened\n");
//Openforwrite
if((stream2=fopen("data2","w+"))==NULL)//C4996
printf("Thefile'data2'wasnotopened\n");
else
printf("Thefile'data2'wasopened\n");
//ClosestreamifitisnotNULL
if(stream)
{
if(fclose(stream))
{
printf("Thefile'crt_fopen.c'wasnotclosed\n");
}
}
//Allotherfilesareclosed:
numclosed=_fcloseall();
printf("Numberoffilesclosedby_fcloseall:%u\n",numclosed);
}
注意
在文件操作時,需要注意以下幾點問題
1、在定義文件指針時,要將文件指針指向空;如 FILE *fp = NULL;
2、文件操作完成后,需要將文件關閉,一定要注意,否則會造成文件所占用內存泄露和在下次訪問文件時出現問題。
3、文件關閉后,需要將文件指針指向空,這樣做會防止出現游離指針,而對整個工程造成不必要的麻煩;如:fp = NULL;
二進制文件
廣義的二進制文件即指文件,由文件在外部設備的存放形式為二進制而得名。狹義的二進制文件即除文本文件以外的文件。文本文件是一種由很多行字符構成的計算機文件。文本文件存在于計算機系統中,通常在文本文件最后一行放置文件結束標志。文本文件的編碼基于字符定長,譯碼相對要容易一些;二進制文件編碼是變長的,靈活利用率要高,而譯碼要難一些,不同的二進制文件譯碼方式是不同的。
從本質上來說他們之間沒有什么區別,因為他們在硬盤上都有一種的存放方式--二進制,但是如果要對他們有些區分的話,那可以這樣理解。每個字符由一個或多個字節組成,每個字節都是用的-128—127之間的部分數值來表示的,也就是說,-128——127之間還有一些數據沒有對應任何字符的任何字節。如果一個文件中的每個字節的內容都是可以表示成字符的數據,我們就可以稱這個文件為文本文件,可見,文本文件只是二進制文件中的一種特例,為了與文本文件相區別,人們又把除了文本文件以外的文件稱為二進制文件,由于很難嚴格區分文本文件和二進制文件的概念,所以我們可以簡單地認為,如果一個文件專門用于存儲文本字符的數據,沒有包含字符以外的其他數據,我們就稱之為文本文件,除此之外的文件就是二進制文件。