2022-10-20讀寫文件

順序讀寫文件

文件打開后可以對其進(jìn)行讀寫操作,打開時(shí)需要指定相應(yīng)的打開模式)。讀寫操作分為順序讀寫操作和隨機(jī)讀寫操作。順序讀寫操作是指打開文件之后從文件頭開始讀寫,即讀寫數(shù)據(jù)的順序和數(shù)據(jù)在文件中的存儲順序是一致的。

讀寫單個(gè)字符

從文件讀取單個(gè)字符可以使用fgetc和getc函數(shù)。這兩個(gè)函數(shù)的作用都是從文件流中讀取下一個(gè)字符并推進(jìn)文件的位置指示器(用來指示要讀寫的下一一個(gè)字符的位置)。

#include <stdio.h>

...

int fgetc (FILE *stream) ;

int getc(FILE *stream) ;

參數(shù)是一個(gè)FILE結(jié)構(gòu)的指針,指定一個(gè)待讀取的文件流。如果讀取成功,該函數(shù)將讀取到的unsigned char 類型轉(zhuǎn)換為int類型并返回:如果文件結(jié)束或者遇到錯(cuò)誤則返回EOF。

fgetc和getc 的功能和描述基本上是一樣的, 它們的區(qū)別主要在于實(shí)現(xiàn): fgetc 是個(gè)函數(shù):而getc實(shí)際上是一個(gè)宏的實(shí)現(xiàn)。一殷來說,宏雖產(chǎn)生較大的代碼量,但是避免了函數(shù)調(diào)用的堆棧操作,所以速度會(huì)比較快。由于getc 是由宏實(shí)現(xiàn)的,對其參數(shù)可能有不止一次的調(diào)用,所以不能使用帶有副作用(side efects)的參數(shù)(所謂副作用,其實(shí)就是參數(shù)中不能存在自增、自減運(yùn)算符,因?yàn)楹暝谡归_后可能參數(shù)會(huì)被多次引用。

向文件寫入單個(gè)字符可以使用fputc和pute函數(shù)。

#include <stdio.h>

...

int fputc(int c, FILE *stream) ;

int putc(int CFILE *stream) ;

與上面一樣,它們的區(qū)別是: fputce 是個(gè)函數(shù), 而pute則是 個(gè)宏的實(shí)現(xiàn)。 它們都有兩個(gè)參數(shù):第一個(gè)參數(shù)指定待寫入的字符:第二個(gè)參數(shù)是一個(gè)FILE結(jié)構(gòu)的指針,指定一個(gè)待寫入的文件流。

讀寫整個(gè)字符串

從文件讀整個(gè)字符串和向文件寫整個(gè)字符串可以使用fgets 和fputs 函數(shù)。

#include <stdio.h>

...

char *fgets (char *S,int size, FILE *stream) ;

int fputs (const char *s, FILE *stream) ;

其中,fgets 函數(shù)用于從指定文件中讀取字符串。fgets 函數(shù)最多可以讀取size -1個(gè)字符,因?yàn)榻Y(jié)尾處會(huì)自動(dòng)添加個(gè)字符串結(jié)束符 (^0)。當(dāng)讀取到換行符 ("n')或文件結(jié)束符(EOF)時(shí),表示結(jié)束讀取("n'會(huì)被作為個(gè)合法的字符讀取)。

fgets函數(shù)有三個(gè)參數(shù):第一個(gè)參數(shù)是一個(gè)字符型指針,指向用于存放讀取到的字符串的位置;第二個(gè)參數(shù)指定讀取的字符數(shù)(包括最后自動(dòng)添加的"0):最后一個(gè)參數(shù)是一個(gè)FILE結(jié)構(gòu)的指針,指定一個(gè)待讀取的文件流。

如果函數(shù)調(diào)用成功,返回第一個(gè)參數(shù)指向的地址。如果在讀取字符的過程中遇到EOF,則eof指示器被設(shè)置:如果還沒讀入任何字符就遇到EOF,則第一個(gè)參數(shù)指向的位置保持原來的內(nèi)容,函數(shù)返回NULL;如果在讀取的過程中發(fā)生錯(cuò)誤,則error指示器被設(shè)置,函數(shù)返回NULL,但第一個(gè)參數(shù)指向的內(nèi)容可能被改變。

將一個(gè)字符串寫入文件中使用fpus 函數(shù)。注意,字符串結(jié)束符("0)不會(huì)被一并寫入。

fputs函數(shù)有兩個(gè)參數(shù):第一個(gè)參數(shù)是一個(gè)字符型指針,指向用于存放待寫入字符串的位置:第二個(gè)參數(shù)是一個(gè)FILE結(jié)構(gòu)的指針,指定一個(gè)待操作的數(shù)據(jù)流。如果函數(shù)調(diào)用成功,返回一個(gè)非0值:如果函數(shù)調(diào)用失敗,返回EOF。

舉個(gè)例子調(diào)用多次fpus函數(shù)將幾個(gè)字符串寫入文件中,然后調(diào)用fgets 函數(shù)讀取并打印到屏幕上

feof函數(shù)用于檢測eof指示器是否被設(shè)置,如果檢測到文件末尾指示器被設(shè)置,返回一個(gè)非0值:否則返回0。

第三行字符串打印了兩次,但是查看lines.txt 文件的內(nèi)容卻是正確的:

分析:這是因?yàn)閒gets 函數(shù)一旦遇到換行符("n')就會(huì)停止本次字符串的讀取,而在最后一行字符串讀取完成之后,并沒有遇到EOF (是換行符導(dǎo)致了本次讀取結(jié)束),所以它還要多讀取一次,但是這一次除了讀取到EOF就沒有其他內(nèi)容了,因此buffer字符串的內(nèi)容并沒有被新的內(nèi)容所覆蓋。

格式化讀寫文件

scanf和printf函數(shù)使用它們可以對終端進(jìn)行格式化字符串輸入和輸出。同樣,對于文件的讀寫,也有兩個(gè)類似的函數(shù)— fscanf 和fprintf函數(shù)。

#include <stdio.h>

...

int fscanf (FILE *stream, const char *format, .. ) ;

int fprintf (FILE *stream, const char*format, .. .) ;

從名字上看,它們只是在scanf和printf前面加上一個(gè)表示文件的f (file); 從用法上看,fscanf 和fprintf函數(shù)的讀寫對象是文件而不是終端,其中的format 參數(shù)和附加參數(shù)用法與scanf和printf函數(shù)是一致的。

二進(jìn)制讀寫文件

雖然fopen函數(shù)可以指定以何種模式(文本模式或二進(jìn)制模式)打開一個(gè)文件,但這并不意味著后續(xù)對該文件的操作就定是對應(yīng)的形式。

代碼中,雖然使用"wb"二進(jìn)制模式打開了一個(gè)text.txt文件,但仍然調(diào)用fputc函數(shù)成功地將四個(gè)字符('51、12'、 '0'和\n') 寫入了文件中。使用xxd命令以十六進(jìn)制的形式查看該文件內(nèi)容,35、32、30和0a分別對應(yīng)的是'5'、'2'、 '0'和"\n'的 ASCII編碼。

C語言為直接讀寫文件提供了fread 和fwrite函數(shù)。

#include <stdio.h>

size_t fread(void*ptr, size_t size,size_t nmemb, FILE *stream) ;

size_t fwrite (const void *ptr,size_t size,size_t nmemb, FILE *stream);

其中,fread 函數(shù)用于從指定文件中讀取指定尺寸的數(shù)據(jù)。該函數(shù)共有四個(gè)參數(shù):第一個(gè)參數(shù)指向存放數(shù)據(jù)的內(nèi)存塊地址:第二個(gè)參數(shù)指定待讀取的每個(gè)元素的尺寸:第三個(gè)參數(shù)指定待讀取的元素個(gè)數(shù):最后一個(gè)參數(shù)是一個(gè)FILE結(jié)構(gòu)的指針,指向一個(gè)待讀取的文件流。

既然是使用文本模式打開的文件,又能夠正常地將內(nèi)容打印到屏幕上,那么file.xt文件中的內(nèi)容定應(yīng)該是文本。 使用vi命令打開file.xt文件來看看

這是典型的二進(jìn)制數(shù)據(jù),因此使用文本編輯器并不能讀取其內(nèi)容。

不難得出結(jié)論:不管是用文本模式還是用二進(jìn)制模式打開文件,都不能決定寫入數(shù)據(jù)的形式,它們只是影響換行符的表現(xiàn)形式而已。真正決定數(shù)據(jù)是以字符的形式寫入還是以二進(jìn)制的形式寫入,則是相關(guān)的文件讀寫函數(shù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • //讀寫分為順序讀寫(從文件開始讀寫)和隨機(jī)讀寫(比如定位文件指示器后讀取第1000個(gè)字節(jié)位置的字符) //***...
    lxr_閱讀 147評論 0 0
  • 一. 基本概念 文件 文件作為數(shù)據(jù)存儲的單位,通常用來長期存儲數(shù)據(jù)。文件中的數(shù)據(jù)是以字節(jié)為單位進(jìn)行順序存儲的。操作...
    山藥魚兒閱讀 750評論 0 5
  • 用Python讀寫文件(指南) 本文為譯文, 原文鏈接:Reading and Writing Files in ...
    東風(fēng)微鳴閱讀 2,229評論 0 7
  • C讀寫文件 使用 fopen(文件名,訪問模式) 函數(shù)來打開文件,一般有g(shù)etc/putc , fgets/fpu...
    來一斤小鮮肉閱讀 215評論 0 0
  • 讀文件 用Python內(nèi)置的open()函數(shù)打開一個(gè)文件 file_name:file_name變量是一個(gè)包含了你...
    Java移動(dòng)技術(shù)棧閱讀 277評論 0 0

友情鏈接更多精彩內(nèi)容