寫完「C語言」單鏈表/雙向鏈表的創建/遍歷/插入/刪除 後,如何將內存中的鏈表信息及時的保存到文件中,又可以及時的從文件中讀取出來進行處理,便須要用到」文件「的相關知識點進行文件的輸入、輸出。html
其實,就算不懂得鏈表,也徹底能夠學習」文件「相關知識點,但在此以前最好有」指針「基礎。數組
本篇文章整理自《C語言程序設計教程--人民郵電出版社》第十二章——文件,以做文件探討。函數
1、數據流與文件概念post
2、文件的打開與關閉學習
3、文件的順序讀寫spa
4、文件的隨機讀寫操作系統
5、出錯檢查設計
6、低級I/O函數與標準I/O函數指針
1、數據流與文件概念code
1.數據流
數據的輸入與輸出都必須經過計算機的外圍設備,不一樣的外圍設備對於數據輸入與輸出的格式和方法有不一樣的處理方式,這就增長了編寫文件訪問程序的困難程度,並且很容易產生外圍設備彼此不兼容的問題。數據流(Data Stream)用來解決這個問題。
數據流將整個文件內的數據看做一串連續的字符(字節),而沒有記錄的限制。
數據流藉助文件指針的移動來訪問數據,文件指針目前所指的位置便是要處理的數據,通過訪問後文件指針會自動向後移動。
每一個數據文件後面都有一個文件結束符號(EOF),用來告知該數據文件到此結束,若文件指針指到EOF便表示數據已訪問完畢。
2.文件
「文件」是指存放在外部存儲介質(能夠是磁盤、光盤、磁帶等)上的數據集合。操做系統對外部介質上的數據是以文件形式進行管理的。當打開一個文件或者建立一個新文件時,一個數據流和一個外部文件(多是一個物理設備)相關聯。
C語言支持的是流式文件,即前面提到的數據流,它把文件看做一個字節序列,以字節爲單位進行訪問,沒有記錄界限,即數據的輸入和輸出的開始和結束僅受程序控制,而不受物理符號(如回車換行符)控制。
能夠從不一樣角度對文件進行分類
(1)根據文件依附的性質——普通文件和設備文件。
(2)根據文件的組織形式——順序讀寫文件和隨機讀寫文件。
(3)根據文件的存儲形式——ASCII碼文件和二進制文件。
ASCII碼文件和二進制文件的主要區別:
(1)存儲形式:ASCII文件將該數據類型轉換爲可在屏幕上顯示的形式存儲,二進制文件是按該數據類型在內存中的存儲形式存儲的。
(2)存儲空間:ASCII所佔空間較多,並且所佔空間大小與數值大小有關。
(3)讀寫時間:二進制文件讀寫時須要轉換,形成存取速度較慢。ASCII碼文件則不須要。
(4)做用:ASCII碼文件一般用於存放輸入數據及程序的最終結果。二進制文件則不能顯示出來,用於暫存程序的中間結果。
在C語言中,標準輸入設備和標準輸出設備是做爲ASCII碼文件處理的,它們分別稱爲標準輸入文件和標準輸出文件。
文件和內存的交互處理:
2、文件的打開與關閉
要打開指定的文件可以使用fopen()函數
FILE *fopen(char *filename,char *mode);
其中第二個參數mode用來設定要打開的文件類型和指定文件的訪問模式。
文件中的訪問模式:
判斷文件是否正確打開
FILE *fp; fp=fopen("文件目錄","文件中的訪問模式"); if(fp==NULL) { printf("\n不能打開該文件!"); getch(); exit(1); }
關閉文件使用fclose()
int fclose(FILE *fp);
返回值爲0則表示關閉成功,若返回非0值則表示有錯誤發生。
由系統打開的標準設備文件,系統會自行關閉。
獲取文件的屬性:
獲取文件描述字:int fileno(FILE *fp);
根據文件描述字獲取對應文件大小:long filelength(int handle_no);
3、文件的順序讀寫
順序讀寫是指將文件從頭至尾逐個數據讀出或寫入。
單字符讀寫函數:fgetc()和fputc():
int fgetc(FILE *fp);
功能爲:讀取文件指針fp目前所指文件位置中的字符,讀取完畢,文件指針自動往下移一個字符位置,若文件指針已經到文件結尾,返回-1。
返回值:成功則返回讀取到的字符,失敗返回-1.
fgetc()函數調用中,讀取的文件必須是以讀或讀寫的方式打開的。
int fputc(char ch,FILE *fp);
功能爲:把字符ch寫入文件指針fp所指向文件的位置。
返回值:成功時返回字符的ASCII碼,失敗時返回EOF(在stdio.h中,符號常量EOF的值等於-1)。
被寫入的字符能夠用寫、讀寫、追加方式打開。
字符串讀寫函數:fgets()和fputs():
char *fgets(char *str,int n,FILE *fp);
功能爲:在文件指針fp所指文件位置讀取n個字符並放入str字符數組。
返回值:若是讀不到字符串時返回NULL。
int fputs(char *str,FILE *fp);
功能爲:將字符串str寫入文件指針fp所指文件的位置。
返回值:寫入數據成功時返回非0值,寫入失敗時返回EOF。
格式化字符串讀寫函數:fscanf()和fprintf():
int fscanf(FILE *fp,"格式化字符串",【輸入項地址表】);
功能爲:從文件指針fp所指向的文件中按照格式字符串指定的格式將文件中的數據送到輸入項地址表中。
返回值:讀取數據成功返回所讀取數據的個數,並將數據按照指定格式存入內存中的變量或數組中,文件指針自動向下移動。讀取失敗返回EOF。
int fprintf(FILE *fp,"格式化字符串",【輸入項地址表】);
功能爲:將輸出項表中的變量值按照格式字符串制定的格式輸出到文件指針fp所指向的文件位置。
返回值:成功返回輸出字符數,失敗則返回負值。
數據塊讀寫函數:fread()和fwrite:
int fread(void *buffer,int size,int count,FILE *fp);
功能爲:從文件指針fp所指向的文件的當前位置開始,一次讀入size個字節,重複count次,並將讀取到的數據存到buffer開始的內存區中,同時將讀寫位置指針後移size*count次。
返回值:該函數的返回值是實際讀取的count值。
int fwrite(void *buffer,int size,int count,FILE *fp);
功能爲:從buffer所指向的內存區開始,一次輸出size個字節,重複count次,並將輸出的數據放入fp所指向的文件中,同時將讀寫位置指針後移size*count次。
返回值:返回實際寫入的數據項個數count。
4、文件的隨機讀寫
隨機讀寫可移動文件內部的位置指針到須要讀寫的位置,再進行讀寫,這種讀寫稱爲隨機讀寫。實現文件的隨機讀寫關鍵是要按要求移動位置指針,這成爲文件的定位。
void rewind(FILE *fp);
功能爲:將文件內部的位置指針移到文件的開始位置。
int fseek(FILE *fp,long offset,int whence);
功能爲:文件指針由whence地址移到offset的地址。
返回值:
對應文件的指針偏移,在函數定義中並無真正的說明清楚返回值,對於offset當爲正數的時候是向文件尾偏移的,當爲負數的時候是向文件頭方向偏移的,這裏主要是要注意偏移的大小和文件大小邊界的關係。
當offset是向文件尾方向偏移的時候,不管偏移量是否超出文件尾,fseek都是返回0,當偏移量沒有超出文件尾的時候,文件指針式指向正常的偏移地址的,當偏移量超出文件尾的時候,文件指針是指向文件尾的。並不會返回偏移出錯-1值。
當offset是向文件頭方向偏移的時候,若是offset沒有超出文件頭,是正常偏移,文件指針指向正確的偏移地址,fseek返回值爲0.當offset超出文件頭時,fseek返回出錯-1值,文件指針不變仍是處於原來的地址。
long ftell(FILE *_File);
功能爲:獲得流式文件的當前位置,用相對於文件開頭的位移量來表示。因爲文件中的位置指針常常移動,人們每每不容易知道其當前位置。用fell函數便可以獲得當前位置。
返回值:若是返回-1L,表示出錯。
int putw(int _Ch,FILE *_File);
功能爲:將整數_Ch輸出到fp指向的文件。
int __cdecl getw(FILE *_File);
功能爲:從磁盤文件都一個整數到內存最爲返回值。
5、出錯檢查
C語言中經常使用文件檢測函數來檢查輸入/輸出函數調用中的錯誤。
int feof(FILE *fp);
功能爲:判斷指針fp是否處於文件結束的位置。
返回值:如文件結束,返回值爲1,不然爲0。
int ferror(FILE *fp);
功能爲:檢查文件在用各類輸入/輸出函數進行讀寫時是否出錯。
返回值:若是ferror返回值爲0表示未出錯,不然表示出錯。
注意:對同一個文件每一次調用輸入/輸出函數,均產生一個新的ferror函數值,所以,應當在執行fopen函數時,ferror函數初始值自動置0。
int clearerr(FILE *fp);
功能爲:本函數用於清除出錯標誌和文件結束標誌,使它們爲0值。假設在調用一個輸入/輸出函數時出現錯誤,ferror函數值爲一個非0值。在調用clearerr(fp)後,ferror(fp)的值變爲0。
只要出現錯誤標誌,就會一直保留,知道對同一文件調用clearerr函數或rewind函數,或任何其餘一個輸入/輸出函數。
6、低級I/O函數與標準I/O函數
系統輸入/輸出函數,或稱低級I/O函數,在內存訪問數據並不提供緩衝區,所以只要一有數據須要作訪問操做時,便直接向磁盤做Disk I/O。此類文件函數的優勢是沒必要佔用內存空間做爲緩衝區,直接向磁盤的數據文件進行讀寫的操做,若是不幸死機,只會影響目前正在讀寫的數據。其缺點就是數據訪問時會形成磁盤I/O次數太過頻繁而影響程序運行的速度,並且此類函數是以文件描述字來代替文件指針,且不提供格式化的處理功能。
因爲現行的C版本,基本使用的都是緩衝文件系統,即標準輸入/輸出函數,因此,關於非緩衝文件系統的系統輸入/輸出函數在這裏就再也不詳細介紹。