C檔案流
這種方式的檔案操作有一個重要的結構FILE,FILE在stdio.h中定義如下: 以下是引用片段:
typedef struct {
int level;
unsigned flags;
char fd;
unsigned char hold;
int bsize;
unsigned char _FAR *buffer;
unsigned char _FAR *curp;
unsigned istemp;
short token;
} FILE;
FILE這個結構包含了檔案操作的基本屬性,對檔案的操作都要通過這個結構的指標來進行,此種檔案操作常用的函式如下,下面是這些函式的功能使用說明:
功能:開啟流
fopen的原型是:FILE *fopen(const char *filename,const char *mode),fopen實現三個功能:為使用而開啟一個流,把一個檔案和此流相連線,給此流返回一個FILR指標。
引數filename指向要開啟的檔名,mode表示開啟狀態的字串,其取值如下:
l "r" 以只讀方式開啟檔案
l "w" 以只寫方式開啟檔案
l "a" 以追加方式開啟檔案
l "r+" 以讀/寫方式開啟檔案,如無檔案出錯
l "w+" 以讀/寫方式開啟檔案,如無檔案生成新檔案
一個檔案可以以文字模式或二進位制模式開啟,這兩種的區別是:在文字模式中回車被當成一個字元'\n'
系統預設的是以文字模式開啟,可以修改全部變數_fmode的值來修改這個設定,例如_fmode=O_TEXT;就設定預設開啟方式為文字模式;而_fmode=O_BINARY;則設定預設開啟方式是二進位制模式。
我們也可以在模式字串中指定開啟的模式,如"rb"表示以二進位制模式開啟只讀檔案,"w+t"或"wt+"表示以文字模式開啟讀/寫檔案。
此函式返回一個FILE指標,所以申明一個FILE指標後不用初始化,而是用fopen()來返回一個指標並與一個特定的檔案相連,如果成敗,返回NULL
例如: 以下是引用片段:
FILE *fp; if(fp=fopen("123.456","wb")) puts("開啟檔案成功"); else puts("開啟檔案成敗"); |
fclose()的功能就是關閉用fopen()開啟的檔案,其原型是:int fclose(FILE *fp);如果成功,返回0,失敗返回EOF。
在程式結束時一定要記得關閉開啟的檔案,不然可能會造成資料丟失的情況,我以前就經常犯這樣的錯誤。
例:fclose(fp);
1.1.3 fputc() 寫一個字元到流中向流寫一個字元,原型是int fputc(int c, FILE *stream); 成功返回這個字元,失敗返回EOF。
例:fputc('X',fp);
1.1.4 fgetc() 從流中讀一個字元從流中讀一個字元,原型是int fputc(FILE *stream); 成功返回這個字元,失敗返回EOF。
例:char ch1=fgetc(fp);
1.1.5 fseek() 在流中定位到指定的字元此函式一般用於二進位制模式開啟的檔案中,功能是定位到流中指定的位置,原型是int fseek(FILE *stream, long offset, int whence);如果成功返回0,引數offset是移動的字元數,whence是移動的基準,取值是:
符號常量 值 基準位置
Ø SEEK_SET 0 檔案開頭
Ø SEEK_CUR 1 當前讀寫的位置
Ø SEEK_END 2 檔案尾部
例:fseek(fp,1234L,SEEK_CUR);//把讀寫位置從當前位置向後移動1234位元組(L字尾表示長整數)
fseek(fp,0L,2);//把讀寫位置移動到檔案尾
1.1.6 fputs() 寫字串到流寫一個字串到流中,原型int fputs(const char *s, FILE *stream);
例:fputs("I Love You",fp);
1.1.7 fgets() 從流中讀一行或指定個字元從流中讀一行或指定個字元,原型是char *fgets(char *s, int n, FILE *stream); 從流中讀取n-1個字元,除非讀完一行,引數s是來接收字串,如果成功則返回s的指標,否則返回NULL。
例:如果一個檔案的當前位置的文字如下:
Love ,I Have
But ……..
如果用
fgets(str1,4,file1);
則執行後str1="Lov",讀取了4-1=3個字元,而如果用
fgets(str1,23,file1);
則執行str="Love ,I Have",讀取了一行(不包括行尾的'\n')。
1.1.8 fprintf() 按格式輸出到流按格式輸入到流,其原型是int fprintf(FILE *stream, const char *format[, argument, …]);其用法和printf()相同,不過不是寫到控制檯,而是寫到流罷了。
例:fprintf(fp,"-%s",4,"Hahaha");
1.1.9 fscanf() 從流中按格式讀取從流中按格式讀取,其原型是int fscanf(FILE *stream, const char *format[, address, …]);其用法和scanf()相同,不過不是從控制檯讀取,而是從流讀取罷了。
例:fscanf(fp,"%d%d" ,&x,&y);
1.1.10 feof() 到達檔案尾時返回真值檢測是否已到檔案尾,是返回真,否則返回0,其原型是int feof(FILE *stream);
例:if(feof(fp))printf("已到檔案尾");
1.1.11 ferror() 發生錯誤時返回其值原型是int ferror(FILE *stream);返回流最近的錯誤程式碼,可用clearerr()來清除它,clearerr()的原型是void clearerr(FILE *stream);
例:printf("%d",ferror(fp));
1.1.12 rewind() 復位檔案定位器到檔案開始處把當前的讀寫位置回到檔案開始,原型是void rewind(FILE *stream);其實本函式相當於fseek(fp,0L,SEEK_SET);
例:rewind(fp);
1.1.13 remove() 刪除檔案刪除檔案,原型是int remove(const char *filename); 引數就是要刪除的檔名,成功返回0。
例:remove("c:\\io.sys");
1.1.14 fread() 從流中讀指定個數的字元從流中讀指定個數的字元,原型是size_t fread(void *ptr, size_t size, size_t n, FILE *stream);引數ptr是儲存讀取的資料,void*的指標可用任何型別的指標來替換,如char*、int *等等來替換;size是每塊的位元組數;n是讀取的塊數,如果成功,返回實際讀取的塊數(不是位元組數),本函式一般用於二進位制模式開啟的檔案中。
例:
以下是引用片段: |
與fread對應,向流中寫指定的資料,原型是size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream);引數ptr是要寫入的資料指標,void*的指標可用任何型別的指標來替換,如char*、int *等等來替換;size是每塊的位元組數;n是要寫的塊數,如果成功,返回實際寫入的塊數(不是位元組數),本函式一般用於二進位制模式開啟的檔案中。
例:
以下是引用片段: |
其原型是FILE *tmpfile(void); 生成一個臨時檔案,以"w+b"的模式開啟,並返回這個臨時流的指標,如果失敗返回NULL。在程式結束時,這個檔案會被自動刪除。
例:FILE *fp=tmpfile();
1.1.17 tmpnam() 生成一個唯一的檔名其原型為char *tmpnam(char *s); 生成一個唯一的檔名,其實tmpfile()就呼叫了此函式,引數s用來儲存得到的檔名,並返回這個指標,如果失敗,返回NULL。
例:tmpnam(str1);
1.2 I/O檔案操作這是C提供的另一種檔案操作,它是通過直接存/取檔案來完成對檔案的處理,而上篇所說流式檔案操作是通過緩衝區來進行;流式檔案操作是圍繞一個FILE指標來進行,而此類檔案操作是圍繞一個檔案的“控制代碼”來進行,什麼是控制代碼呢?它是一個整數,是系統用來標識一個檔案(在WINDOWS中,控制代碼的概念擴充套件到所有裝置資源的標識)的唯一的記號。此類檔案操作常用的函式如下表,這些函式及其所用的一些符號在io.h和fcntl.h中定義,在使用時要加入相應的標頭檔案。
下面就對這些函式一一說明:
1.2.1 open()開啟一個檔案並返回它的控制代碼開啟一個檔案並返回它的控制代碼,如果失敗,將返回一個小於0的值,原型是int open(const char *path, int access [, unsigned mode]); 引數path是要開啟的檔名,access是開啟的模式,mode是可選項。表示檔案的屬性,主要用於UNIX系統中,在DOS/WINDOWS這個引數沒有意義。其中檔案的開啟模式如下表。
符號含義
l O_RDONLY 只讀方式
l O_WRONLY 只寫方式
l O_RDWR 讀/寫方式
l O_NDELAY 用於UNIX系統
l O_APPEND 追加方式
l O_CREAT 如果檔案不存在就建立
l O_TRUNC 把檔案長度截為0
l O_EXCL 和O_CREAT連用,如果檔案存在返回錯誤
l O_BINARY 二進位制方式
l O_TEXT 文字方式
對於多個要求,可以用"|"運算子來連線,如O_APPEND|O_TEXT表示以文字模式和追加方式開啟檔案。
例:int handle=open("c:\\msdos.sys",O_BINARY|O_CREAT|O_WRITE)
1.2.2 close()關閉一個控制代碼關閉一個控制代碼,原型是int close(int handle);如果成功返回0。
例:close(handle)
1.2.3 lseek()定位到檔案的指定位置定位到指定的位置,原型是:long lseek(int handle, long offset, int fromwhere);引數offset是移動的量,fromwhere是移動的基準位置,取值和前面講的fseek()一樣,SEEK_SET:檔案首部;SEEK_CUR:檔案當前位置;SEEK_END:檔案尾。此函式返回執行後文件新的存取位置。例:
lseek(handle,-1234L,SEEK_CUR);//把存取位置從當前位置向前移動1234個位元組。
x=lseek(hnd1,0L,SEEK_END);//把存取位置移動到檔案尾,x=檔案尾的位置即檔案長度
1.2.4 read()塊讀檔案從檔案讀取一塊,原型是int read(int handle, void *buf, unsigned len);引數buf儲存讀出的資料,len是讀取的位元組。函式返回實際讀出的位元組。
例:char x[200];read(hnd1,x,200);
1.2.5 write()塊寫檔案寫一塊資料到檔案中,原型是int write(int handle, void *buf, unsigned len);引數的含義同read(),返回實際寫入的位元組。
例:char x[]="I Love You";write(handle,x,strlen(x));
1.2.6 eof()測試檔案是否結束類似feof(),測試檔案是否結束,是返回1,否則返回0;原型是:int eof(int handle);
例:while(!eof(handle1)){……};
1.2.7 filelength()取得檔案長度返回檔案長度,原型是long filelength(int handle);相當於lseek(handle,0L,SEEK_END)
例:long x=filelength(handle);
1.2.8 rename()重新命名檔案重新命名檔案,原型是int rename(const char *oldname, const char *newname); 引數oldname是舊檔名,newname是新檔名。成功返回0
例:rename("c:\\config.sys","c:\\config.w40");
1.2.9 chsize();改變檔案長度