個人主頁
今天我們來講一下有關文件的相關操作,希望看完這篇文章對你有所幫助,大力感謝你對博主的支持!
文章目錄
- ?一、為什么使用文件
- 🎉二、什么是文件
- 2.1 程序文件
- 2.2 數據文件
- 2.3 文件名
- 🎡三、二進制文件和文本文件
- 🚀四、文件的打開和關閉
- 4.1 流和標準流
- 4.2 文件指針
- 4.3 文件的打開和關閉
- 🏝?五、文件的順序讀寫
- 5.1 fgetc (字符輸入函數)
- 5.2 fputc (字符輸出函數)
- 5.3 fgets (文本行輸入函數)
- 5.4 fputs (文本行輸出函數)
- 5.5 fscanf (格式化輸入函數)
- 5.6 fprintf (格式化輸出函數)
- 5.7 fread (二進制輸入)
- 5.8 fwrite (二進制輸出)
- 🎄六、文件的隨機讀寫
- 6.1 fseek
- 6.2 ftell
- 6.3 rewind
- 🚆七、文件讀取結束的判定
- 🚘八、文件緩沖區
?一、為什么使用文件
在日常中,我們寫的程序的數據是存儲在電腦的內存中,如果程序退出,內存就會被回收,數據就丟失了。我們再次運行程序時就看不到上次程序的數據。因此像要將數據進行持久化的保存,我們就需要使用文件。
🎉二、什么是文件
磁盤(硬盤)上的文件是文件。
但是在設計程序中,我們一般把文件分為兩種:一是程序文件,另一個是數據文件。(從文件功能的角度進行分類)
2.1 程序文件
程序文件包括源程序文件(后綴為.c),目標文件(windows環境后綴為.obj),可執行程序(windows
環境后綴為.exe)。
2.2 數據文件
程序運行時讀寫的數據,比如程序運行需要從中讀取數據的文件,或者輸出內容的文件。
2.3 文件名
文件名包含3部分:文件路徑+文件名主干+文件后綴
例如:c:\code\test.txt
注意:文件標識常被稱為文件名。
🎡三、二進制文件和文本文件
數據在內存中以二進制的形式存儲,如果不加轉換的輸出到外存的文件中,就是二進制文件。
如果要求在外存上以ASCII碼的形式存儲,則需要在存儲前轉換。以ASCII字符的形式存儲的文件就是文本文件。
我們以二進制存儲的方式舉例:
int main()
{int a = 10000;FILE * pf = fopen("test.txt", "wb");fwrite(&a, 4, 1, pf);//?進制的形式寫到?件中 fclose(pf);pf = NULL;return 0;
}
由于我們是以二進制的存儲方式,因此打開文件的方式也要用二進制的打開方式
編譯器是以小端存儲且以16進制的方式進行打印
🚀四、文件的打開和關閉
4.1 流和標準流
流
? 由于我們程序的數據需要輸出到各種外部設備,也需要從外部設備獲取數據,而不同的外部設備的輸入和輸出操作各不相同,因此為了程序員方便操作,抽象出了流的概念,我們可以把流想象成流淌著字符的河。
? C程序針對文件、畫面和鍵盤等的數據輸入和輸出操作都是通過流來進行操作的。
? 一般情況下,我們要想向從流里寫數據,或者從流中讀取數據,都是需要打開流,然后操作。
標準流
為什么我們從鍵盤中輸入數據,向屏幕上輸出數據時,并沒有打開流呢?那是因為C語言程序在啟動的時候,默認打開了3個流:
? stdin - 標準輸入流,在大多數的環境中從鍵盤輸入,scanf函數就是從標準輸入流中讀取數據。
? stdout - 標準輸出流,大多數的環境中輸出至顯示器界面時,printf函數就是將信息輸出到標準輸出流中。
? stderr - 標準錯誤流,大多數環境中輸出到顯示器界面。
4.2 文件指針
緩沖文件系統中,關鍵的概念是 “文件類型指針”,簡稱“文件指針”
每個被使用的文件都在內存中開辟了?個相應的文件信息區,用來存放文件的相關信息(如文件的名字,文件狀態以及文件當前的位置等)。這些信息是保存在?個結構體變量中的。該結構體類型是由系統聲明的,取名FILE
4.3 文件的打開和關閉
文件在讀寫之前應該先打開文件,在使用結束之后應該關閉文件。
ANSIC規定使用 fopen 函數來打開文件, fclose 函數來關閉文件。
//打開?件
FILE * fopen ( const char * filename, const char * mode );//關閉?件 int fclose ( FILE * stream );
文件的打開模式有很多種,例如:“r” 表示輸入數據,打開一個已經存在的文本文件;“w” 表示輸出數據,打開一個文本文件,若該文件不存在則建立一個新文件;“a” 表示向文本文件末尾添加數據等等,這里就不一一贅述了。
下面我們就以寫的方式舉個例子:
🏝?五、文件的順序讀寫
5.1 fgetc (字符輸入函數)
函數形式:int fgetc ( FILE * stream );
該函數成功讀入數據時會返回讀取字符的ASCII值,否則則會返回EOF。
例如:假如.c路徑下有一文件名叫test.txt,該文件中有字符串”abcdef"
5.2 fputc (字符輸出函數)
函數形式:int fputc ( int character, FILE * stream );
該函數返回文件指針當前指向的字符,文件指針向后移動一位
如果文件指針位于文件末尾,那么就返回EOF,并為流設置feof的文件結束顯示器
如果文件讀取錯誤,同樣返回EOF,為流設置為錯誤顯示器ferror
例如:向一個文件寫入26個小寫英文字符
5.3 fgets (文本行輸入函數)
函數形式:char * fgets ( char * str, int num, FILE * stream );
從流中讀取字符,并以字符串的形式存儲到str中。 直到讀夠(num - 1)個字符,或到達換行符,或讀到文件末尾時才停止
如果讀取成功,則返回str的頭指針,若讀取失敗,則為流設置錯誤顯示器,并返回空指針。
5.4 fputs (文本行輸出函數)
函數形式:int fputs ( const char * str, FILE * stream );
將str中的字符串輸出到流中,結束符‘\0’不會被寫入
5.5 fscanf (格式化輸入函數)
函數形式:int fscanf ( FILE * stream, const char * format, ... );
以格式化的形式從流中讀取數據
例如:從文件中讀取字符串 “abcd”
5.6 fprintf (格式化輸出函數)
函數形式:int fprintf ( FILE * stream, const char * format, ... );
將格式化的數據輸出到指定流。
5.7 fread (二進制輸入)
函數形式:size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
以二進制的形式從流中讀取count個元素,每個元素的大小為size字節,并將它們存儲在 ptr 指定的內存塊中。
返回成功讀取的元素總數。
5.8 fwrite (二進制輸出)
函數形式:size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
以二進制的形式將ptr存儲的數據寫入流中,一共寫入count個元素,每個元素的大小為size字節
返回成功寫入的元素總數。
int main()
{int a = 10000;FILE * pf = fopen("test.txt", "wb");fwrite(&a, 4, 1, pf);//?進制的形式寫到?件中 fclose(pf);pf = NULL;return 0;
}
🎄六、文件的隨機讀寫
6.1 fseek
函數形式:int fseek ( FILE * stream, long int offset, int origin );
offset為偏移量
origin為起始位置,有三種取值:
SEEK_SET:文件頭
SEEK_CUR:文件指針的當前位置
SEEK_END:文件尾
如果成功,則返回0,否則返回非零值
例如:在data.txt文件中有字符串"abcdefghi",從a的位置偏移四位就得到f
6.2 ftell
函數形式:long int ftell ( FILE * stream );
返回文件指針相對于起始位置的偏移量
假設.c路徑上的data.txt文件中存儲字符串“abcdefghijk”
6.3 rewind
函數形式:void rewind ( FILE * stream );
讓文件指針的位置回到文件起始位置
🚆七、文件讀取結束的判定
牢記:在文件讀取過程中,不能用feof函數的返回值直接來判斷文件的是否結束。
feof 的作用是:當文件讀取結束的時候,判斷是讀取結束的原因是否是遇到文件尾結束。
? 文本文件讀取是否結束,判斷返回值是否為 EOF
? fgetc 判斷是否為 EOF
? fgets 判斷返回值是否為 NULL
二進制文件的讀取結束判斷: 判斷返回值是否小于實際要讀的個數
🚘八、文件緩沖區
ANSIC標準采用“緩沖文件系統”來處理的數據文件的,所謂緩沖文件系統,是指系統能自動地在內存中為程序中每?個正在使用的文件開辟?塊“文件緩沖區”。從內存向磁盤輸出數據會先送到內存中的緩沖區,裝滿緩沖區后才?起送到磁盤上。
緩沖區的大小根據C編譯系統決定的。
今天的分享到這里就結束了,如果感到對你有所幫助,希望給博主一鍵三連,你的支持就是對博主最大的鼓勵,我們下期再見!