C语言—文件基础
目錄
- 文件概述
- 文件的定義
- 文件的分類
- 文件類型指針
- 文件函數
- 文件的打開(fopen函數)
- 文件的關閉(fclose函數)
- 當前活動指針(ftell 函數)
- rewind()函數
- 設置當前位置(fseek 函數)
- 字符輸入輸出函數(fputc()和fgetc())
- fwrite()函數
- fread()函數
- 格式化讀寫函數(fprintf()和fscanf())
- putw()和getw()
- fgets函數
- fputs函數
- ferror函數(出錯的檢測)
- clearerr函數(出錯的檢測)
文件概述
文件的定義
所謂文件一般指存儲在外部介質(如磁盤磁帶)上數據的集合.
操作系統(tǒng)是以文件為單位對數據進行管理的.
文件的分類
①從操作系統(tǒng)的角度看,每一個與主機相連的輸入輸出設備看作是一個文件。
例:輸入文件:終端鍵盤
輸出文件:顯示屏和打印機
②從用戶觀點:
特殊文件(標準輸入輸出文件或標準設備文件)
普通文件(磁盤文件)
③按數據的組織形式:
ASCII文件(文本文件):每一個字節(jié)放一個ASCII代碼二進制文件:把內存中的數據按其在內存中的存儲形式原樣輸出到磁盤上存放.
例:整數10000在內存中的存儲形式以及分別按ASCII碼形式和二進制形式輸出如下圖所示:
ASCII文件和二進制文件的比較:
1、ASCII文件便于對字符進行逐個處理,也便于輸出字符。但一般占存儲空間較多,而且要花費轉換時間。
2、二進制文件可以節(jié)省外存空間和轉換時間,但一個字節(jié)并不對應一個字符,不能直接輸出字符形式。
3、一般中間結果數據需要暫時保存在外存上,以后又需要輸入內存的,常用二進制文件保存。
④文件的處理方法:
緩沖文件系統(tǒng):系統(tǒng)自動地在內存區(qū)為每一個正在使用的文件開辟一個緩沖區(qū)。用緩沖文件系統(tǒng)進行的輸入輸出又稱為高級磁盤輸入輸出。
非緩沖文件系統(tǒng):系統(tǒng)不自動開辟確定大小的緩沖區(qū),而由程序為每個文件設定緩沖區(qū)。用非緩沖文件系統(tǒng)進行的輸入輸出又稱為低級輸入輸出系統(tǒng)。
文件類型指針
在緩沖文件系統(tǒng)中,每個被使用的文件都要在內存中開辟一FILE類型的區(qū),存放文件的有關信息。stdio.h 中定義了一個稱為 FILE 的結構.
文件指針所需的唯一聲明為:FILE *fp;
文件指針指向一個結構,該結構包含以下信息:文件名、文件的當前位置、文件是否正在讀或寫、是否出錯或是否到達文件末尾
文件緩沖區(qū)示意圖:
文件操作基本流程:
文件函數
| 打開文件 | fopen() | 打開文件 |
| 關閉文件 | fclose() | 關閉文件 |
| 文件定位 | fseek() | 改變文件位置指針的位置 |
| Rewind() | 使文件位置指針重新至于文件開頭 | |
| Ftell() | 返回文件位置指針的當前值 | |
| 文件狀態(tài) | feof() | 若到文件末尾,函數值為真 |
| ferror() | 若對文件操作出錯,函數值為真 | |
| clearerr() | 使ferror和feof()函數值置零 |
文件的打開(fopen函數)
函數調用:
FILE *fp; fp=fopen(文件名,使用文件方式);①需要打開的文件名,也就是準備訪問的文件的名字;
②使用文件的方式(“讀”還是“寫”等);
③讓哪一個指針變量指向被打開的文件。
文件的打開與關閉:
“r” (只讀)為輸入,打開一個文本文件
“w” (只寫)為輸出,打開一個文本文件
“a” (追加)向文本,文件尾增加數據
“rb” (只讀)為輸入,打開一個二進制文件
“wb” (只寫)為輸出,打開一個二進制文件
"ab“ (追加)向二進制文件尾增加數據
"r+“ (讀寫)為讀/寫打開一個文本文件
"w+” (讀寫)為讀/寫建立一個新的文本文件
“a+” (讀寫)為讀/寫打開一個文本文件(追加)
"rb+“ (讀寫)為讀/寫打開一個二進制文件
“wb+“ (讀寫)為讀/寫建立一個新的二進制文件
“ab+” (讀寫)為讀/寫打開一個二進制文件
“r+” 與"w+"兩種方式打開的區(qū)別?
當第一次打開一個文件時,文件不存在,則需要對文件進行創(chuàng)建(程序創(chuàng)建,不是人工手動創(chuàng)建),如果用r+這種模式open的話會返回失敗,如果用w+,當第二次打開這個文件時就會重新創(chuàng)建一個新的文件,那么原來文件里的數據就會丟失。
文件的關閉(fclose函數)
函數調用:
fclose(文件指針);
函數功能:
使文件指針變量不指向該文件,也就是文件指針變量與文件“脫鉤”,此后不能再通過該指針對原來與其相聯(lián)系的文件進行讀寫操作
返回值:
關閉成功返回值為0;否則返回EOF(-1)
當前活動指針(ftell 函數)
FILE 結構提供了一個指針,用以跟蹤發(fā)生 I/O 操作的位置,每當從流中讀取或寫入一個字符,當前活動指針(即 curp)就會向前移動,當前活動指針的當前位置可以借助 ftell() 函數來獲得。
函數原型:long int ftell(FILE *fp);
返回值:成功時返回文件指針位置,否則返回-1
rewind()函數
功能說明:將文件位置指示器置于文件開頭相當于reset(重置)文件指針
函數原型:void rewind(FILE * fp) ;
設置當前位置(fseek 函數)
功能說明:通過指定相對于開始位置、當前位置或流的末尾位置的字節(jié)數來重定位 curp,這取決于 fseek() 函數中指定的位置
函數原型:int fseek (FILE *fp, long int offset, int origin);
參數:
fp:需設置的文件指針
offset:偏移量
origin:搜索的起始位置
返回值:無
origin 表示搜索的起始位置,有以下幾個值:
SEEK_CUR 或 1 :當前文件指針的位置
SEEK_END 或 2 :文件末尾
SEEK_SET 或 0 :文件開始
fseek和ftell的綜合應用,示例:
int main() {FILE *fp;int nLength = 0;fp =fopen(“1.txt”,”r+”);if(fp == NULL){printf(“open failed\n”);return -1;}fseek(fp,0,SEEK_END);//偏移到文件尾部nLength = ftell(fp);//獲取當前文件指針離文件開頭的字節(jié)數printf(“the file length is %d\n”, nLength);fclose(fp); }字符輸入輸出函數(fputc()和fgetc())
1、fputc()函數
函數調用:int fputc(int ch,FILE *fp) ;
函數功能:
將字符(ch的值)輸出到fp所指向的文件中去。
返回值:
如果輸出成功,則返回值就是輸出的字符;
如果輸出失敗,則返回一個EOF.
2、fgetc()函數
函數調用:int fgetc(FILE *fp)
函數功能:
從指定的文件讀入一個字符,該文件必須是以讀或讀寫方式打開的。
返回值:
讀取成功一個字符,賦給ch。如果遇到文件結束符,返回一個文件結束標志
EOF 。
常見的讀取字符操作:
①從一個文本文件順序讀入字符并在屏幕上顯示出來:
#include<stdio.h> #include <stdlib.h> #include <string.h> int main() {FILE *fp;char ch;char string[ ] = "This is a test";fp = fopen("1.txt","w+");fwrite(string, strlen(string), 1, fp); //將string寫入文件fseek(fp, 0, SEEK_SET); //將文件指針設到起始位置ch = fgetc(fp);while(ch != EOF){putchar(ch);ch = fgetc(fp);} return 0; }注意:EOF不是可輸出字符,因此不能在屏幕上顯示。由于字符的ASCII碼不可能出現-1,因此EOF定義為-1是合適的。當讀入的字符值等于-1時,表示讀入的已不是正常的字符而是文件結束符。
②從一個二進制文件順序讀入字符:
#include<stdio.h> #include <stdlib.h> #include <string.h> int main() {FILE *fp;char ch;char string[ ] = "This is a test";fp = fopen("1.dat","w+");fwrite(string, strlen(string), 1, fp);fseek(fp, 0, SEEK_SET);while(!feof(fp)) //判斷文件不是真的結束,循環(huán){ch = fgetc(fp);putchar(ch);} return 0; }注意:ANSI C提供一個feof()函數來判斷文件是否真的結束。如果是文件結束,函數feof(fp)的值為1(真);否則為0(假)。以上也適用于文本文件的讀取。
fwrite()函數
功能說明:fwrite是無格式寫函數,用于向文件寫入整塊的數據。最有價值的一個應用就是讀寫用戶定義的數據類型,尤其是結構。
函數原型:size_t fwrite(const void *buffer,size_t bytes, sizeo_t n,FILE *fp);
參數:buffer:要寫入數據的首地址
bytes:一個單元占字節(jié)數
n:寫入幾個單元
fp:操作的文件指針
返回值:成功時返回寫入的單元數,否則返回0
fread()函數
功能說明:fread是無格式讀函數,用于向文件讀出整塊的數據。經常用fwrite函數寫入,讀取時用fread函數
函數原型:size_t fread(void *buffer, size_t bytes, sizeo_t n, FILE *fp);
參數:buffer:接收緩沖區(qū)的首地址
bytes:一個單元占字節(jié)數
n:讀出幾個單元
fp:操作的文件指針
返回值:成功時返回讀出的單元數,否則返回0
fread與fwrite實例:
#include<stdio.h> #include <stdlib.h> #include <string.h>int main() {FILE *fp;char ch;char string[1024] = "This is a test";char rdata[1024];fp = fopen("1.txt","w+");fwrite(string, sizeof(string), 1, fp);fseek(fp, 0, SEEK_SET);fread(rdata,sizeof(rdata),1,fp); //這里fread的sizeof的大小和fwrite的一直,不然會打印結果后出現亂碼或顯示不全printf("rdata = %s\n",rdata);return 0; }運行結果: rdata = This is a test格式化讀寫函數(fprintf()和fscanf())
函數調用:
int fscanf(文件指針,格式字符串,輸入表列);
int fprintf(文件指針,格式字符串,輸出表列);
函數功能:
從磁盤文件中讀入或輸出字符。
例:
fprintf(fp,"%d,%6.2f",i,t); fscanf(fp,"%d,%f",&i,&t);注意:用fprintf和fscanf函數對磁盤文件讀寫,使用方便,容易理解,但由于在輸入時要將ASCII碼轉換為二進制形式,在輸出時又要將二進制形式轉換成字符,花費時間比較多。因此,在內存與磁盤頻繁交換數據的情況下,最好不用fprintf和fscanf函數,而用fread和fwrite函數。
putw()和getw()
函數調用:
int putw(int w,FILE * fp);
int getw(FILE * fp);
函數功能: 對磁盤文件中讀寫一個字(以二進制形式從文件流中讀取整數)。
注意:putw()和getw()都是按二進制輸入輸出的。所以如果你用putw()輸入數據到文件后以文本的方式打開看到的將都是亂碼。
同樣如果你在文本文件中輸入了數字并保存,用getw()來讀入的話讀入的結果并不是你想象的那樣,因為它是按二進制讀的。
實例:
#include<stdio.h> #include <stdlib.h> #include <string.h>int main() {FILE *fp;int w;fp = fopen("2.txt","wb"); //以二進制形式寫putw(5,fp); fclose(fp);fp = fopen("2.txt","rb");//以二進制形式讀w = getw(fp);printf("Successful read: w = %d\n", w);fclose(fp);return 0; }fgets函數
函數作用:從指定文件讀入一個字符串。
函數調用:fgets(str,n,fp);
從fp指向的文件輸入n-1個字符,在最后加一個’\0’
返回值:str的首地址
fputs函數
函數作用:
向指定的文件輸出一個字符串。
函數調用:fgets("china",fp);
第一個參數可以是字符串常量、字符數組名或字符型
指針。字符串末尾的′\0′不輸出。
返回值:
輸入成功,返回值為0;
輸入失敗,返回EOF.
ferror函數(出錯的檢測)
調用形式:ferror(fp);
返回值:返回0,表示未出錯;返回非0,表示出錯。
在調用一個輸入輸出函數后立即檢查ferror函數的值,否則信息會丟失。在執(zhí)行fopen函數時,ferror函數的初始值自動置為0。
clearerr函數(出錯的檢測)
調用形式:clearerr(fp);
函數作用:使文件錯誤標志和文件結束標志置為0。
只要出現錯誤標志,就一直保留,直到對同一文件調用clearerr函數或rewind函數,或任何其他一個輸入輸出函數。
總結
- 上一篇: C语言—通用链表
- 下一篇: C语言—静态存储与动态存储