Linux 标准I/O函数库
標(biāo)準(zhǔn)I/O函數(shù)庫(kù):
C標(biāo)準(zhǔn)庫(kù)提供了文件的標(biāo)準(zhǔn) I/O 函數(shù)庫(kù),相比前述的系統(tǒng)調(diào)用,主要差別是實(shí)現(xiàn)了跨平臺(tái)的用戶(hù)態(tài)緩沖的解決方案。標(biāo)準(zhǔn)I/O庫(kù)使
用簡(jiǎn)單,與系統(tǒng)調(diào)用I/O相似,也包括打開(kāi)、讀寫(xiě)、關(guān)閉這些操作,主要的函數(shù)列舉如下。
◆ 打開(kāi)與關(guān)閉文件:fopen,fclose。
◆ 讀寫(xiě)文件:fread,fwrite。
◆ 讀寫(xiě)文本行:fgets,fputs。
◆ 格式化讀寫(xiě):fscanf,fprintf。
◆ 標(biāo)準(zhǔn)輸入輸出:printf,scanf。
◆ 讀寫(xiě)字符:fgetc,getc,getchar,fputc,putc,putchar。
◆ 其他:fflush,fseek。
所謂標(biāo)準(zhǔn) I/O 函數(shù)實(shí)際上是對(duì)底層系統(tǒng)調(diào)用的包裝,最終讀寫(xiě)設(shè)備或文件的操作仍需調(diào)用系統(tǒng)I/O函數(shù)來(lái)完成。
兩個(gè)重要的概念:文件指針和流。
標(biāo)準(zhǔn)I/O函數(shù)并不直接操作文件描述符,而是使用文件指針。文件指針與文件描述符是一一對(duì)應(yīng)的關(guān)系,這種對(duì)應(yīng)關(guān)系由標(biāo)準(zhǔn)I/O庫(kù)
自己內(nèi)部維護(hù)。應(yīng)用程序調(diào)用時(shí),只需要提供文件指針即可。文件指針指向的數(shù)據(jù)類(lèi)型為FILE型,但應(yīng)用程序無(wú)須關(guān)系它的具體內(nèi)容。
在標(biāo)準(zhǔn)I/O中,一個(gè)打開(kāi)的文件稱(chēng)為流(stream),流可以用于讀(輸入流)、寫(xiě)(輸出流)或者是讀寫(xiě)(輸入輸出流)。每個(gè)進(jìn)
程在啟動(dòng)后就會(huì)打開(kāi)三個(gè)流,與打開(kāi)的三個(gè)文件相對(duì)應(yīng):stdin代表標(biāo)準(zhǔn)輸入流,stdout代表標(biāo)準(zhǔn)輸出流,stderr代表標(biāo)準(zhǔn)錯(cuò)誤輸出流,它
們都是(FILE*)型的指針。
標(biāo)準(zhǔn)錯(cuò)誤輸出流不進(jìn)行緩沖,輸出的內(nèi)容會(huì)馬上同步到文件(控制臺(tái)設(shè)備)。
與標(biāo)準(zhǔn) I/O 相關(guān)的定義和聲明都放在以下頭文件中:#include <stdio.h>
fopen:
fopen函數(shù)用于打開(kāi)一個(gè)文件流,其原型如下:
FILE *fopen(const char *filename, const char *mode);
◆ filename:被打開(kāi)的文件的名稱(chēng)(可包含路徑)。
◆ mode:字符串,用于表示打開(kāi)的模式。
◆ 返回值:打開(kāi)成功后的文件指針,失敗則返回NULL。
mode如下:
字符串 含義
r 或 rb 以只讀方式打開(kāi)
w 或 wb 以只寫(xiě)方式打開(kāi),若文件有內(nèi)容,則清空
a 或 ab 以只寫(xiě)方式打開(kāi),原內(nèi)容保留,寫(xiě)入的內(nèi)容附加在文件流尾部
r+ 或 rb+ 或 r+b 以更新方式打開(kāi),此時(shí)文件可讀可寫(xiě)
w+ 或 wb+ 或 w+b 以更新方式打開(kāi),文件可讀可寫(xiě),但打開(kāi)時(shí)清空文件內(nèi)容
a+ 或 ab+ 或 a+b 以更新方式打開(kāi),文件可讀可寫(xiě),寫(xiě)入的內(nèi)容附加在文件流尾部
fread 和 fwrite:
fread函數(shù)用于從打開(kāi)的文件流中讀數(shù)據(jù),其原型如下:
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
◆ ptr:指向用于存放讀取到的數(shù)據(jù)的緩沖區(qū)。
◆ size:被讀取的數(shù)據(jù)塊的長(zhǎng)度。
◆ nitems:要讀取的數(shù)據(jù)塊的個(gè)數(shù)。
◆ stream:被讀取的文件指針。
◆ 返回值:實(shí)際讀取到的數(shù)據(jù)塊的個(gè)數(shù)。
使用 fread 函數(shù)需要注意的是,它以數(shù)據(jù)塊(或稱(chēng)記錄)為單位進(jìn)行讀取,返回值也是成功讀取的數(shù)據(jù)塊的個(gè)數(shù),而不是字節(jié)數(shù)
,這個(gè)數(shù)目有可能比要讀取的個(gè)數(shù) nitems 少。
fwrite 函數(shù)用于向打開(kāi)的文件流寫(xiě)入數(shù)據(jù),其原型如下:
size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream);
◆ ptr:指向存放寫(xiě)入數(shù)據(jù)的緩沖區(qū)。
◆ size:要寫(xiě)入的數(shù)據(jù)塊的長(zhǎng)度。
◆ nitems:要寫(xiě)入的數(shù)據(jù)塊的個(gè)數(shù)。
◆ stream:要寫(xiě)入的文件指針。
◆ 返回值:實(shí)際寫(xiě)入的數(shù)據(jù)塊的個(gè)數(shù)。
與 fread 函數(shù)類(lèi)似,fwrite 函數(shù)也是數(shù)據(jù)塊為單位向文件流寫(xiě)入數(shù)據(jù)的。
fclose:
fclose 函數(shù)用于關(guān)閉文件,其原型如下:
int fclose(FILE *stream);
這個(gè)函數(shù)可以改變 stream 參數(shù)所代表的文件,如果改變成功則返回 0,否則將返回 EOF 并且設(shè)置變量 errno 的值以指示錯(cuò)誤。
改變前會(huì)自動(dòng)將文件流中的數(shù)據(jù)寫(xiě)入文件。
fflush:
fflush 函數(shù)用于將文件流中的數(shù)據(jù)更新到真實(shí)的文件中,其原型如下:
int fflush(FILE *stream);
其中參數(shù) stream 是要操作的文件指針,如果更新成功則返回 0,否則將返回 EOF 并且設(shè)置變量 errno 的值以指示錯(cuò)誤。
在用 fclose 關(guān)閉文件前,系統(tǒng)會(huì)自動(dòng)調(diào)用 fflush 更新數(shù)據(jù)。
fseek 和 ftell:
fseek 用于移動(dòng)文件流的讀寫(xiě)位置,其原型如下:
int fseek(FILE *stream, long offset, int whence);
◆ stream:被操作的文件指針。
◆ offset:讀寫(xiě)位置的偏移量。
◆ whence:用于指定偏移量的相對(duì)啟點(diǎn)。
◆ 返回值:0 表示操作成功, -1 表示操作失敗并且設(shè)置 errno 變量的值為錯(cuò)誤碼。
whence 參數(shù)的取值及含義:
◆ SEEK_SET:表示偏移量相對(duì)于文件的開(kāi)頭。
◆ SEEK_CUR:表示偏移量相對(duì)于當(dāng)前的讀寫(xiě)位置。
◆ SEEK_END:表示偏移量相對(duì)于文件末尾。
如果要將讀寫(xiě)位置移動(dòng)到文件的開(kāi)頭,還可以使用這個(gè)函數(shù):
void rewind(FILE *stream);
ftell 函數(shù)可以得到文件流的讀寫(xiě)位置,其原型:
long ftell(FILE *stream);
參數(shù) stream 是文件指針,返回值就是文件流的當(dāng)前讀寫(xiě)位置(相對(duì)于文件開(kāi)頭)。
fgetc,getc,getchar:
fgetc 函數(shù)用于從文件流中讀取一個(gè)字符,其原型如下:
int fgetc(FILE *stream);
與它功能相同的函數(shù)時(shí) getc,原型如下:
int getc(FILE *stream);
其中 stream 參數(shù)是要讀取的文件流。它們返回值雖然是整型,但實(shí)際表示的是讀到的字符,只不過(guò)進(jìn)行了類(lèi)型轉(zhuǎn)換。如果讀操作
發(fā)送錯(cuò)誤或者到達(dá)文件尾,則返回值是 EOF。
getc 與 fgetc 的區(qū)別在于它可能是由宏定義實(shí)現(xiàn)的,因此參數(shù)可能在宏展開(kāi)以后被使用多長(zhǎng),如果參數(shù)本身是一個(gè)表達(dá)式就會(huì)被
多長(zhǎng)求值,這種情況在使用中應(yīng)該避免。
getchar 函數(shù)用于從標(biāo)準(zhǔn)輸入流讀取一個(gè)字符,其原型如下:
int getchar(void);
實(shí)際上對(duì) getchar 的調(diào)用完成等價(jià)于一下函數(shù)的調(diào)用:
getc(stdin);
fputc,putc 和 putchar:
fputc 函數(shù)用于向文件流寫(xiě)入一個(gè)字符,其原型如下:
int fputc(int c, FILE *stream);
putc 函數(shù)與它的功能相同:
int putc(int c, FILE *stream);
◆ c:是要寫(xiě)入的字符,它雖然是整型,但寫(xiě)入時(shí)會(huì)將其轉(zhuǎn)換為無(wú)符號(hào)字符型。
◆ stream:要寫(xiě)入的文件指針。
◆ 返回值:寫(xiě)入的字符轉(zhuǎn)換成整型后的值,發(fā)送錯(cuò)誤則返回 EOF。
putc 函數(shù)與fputc函數(shù)的區(qū)別在于它有可能是用宏定義實(shí)現(xiàn)的。
putchar 用于向標(biāo)準(zhǔn)輸出寫(xiě)入一個(gè)字符:
int putchar(int c);
與putc等同:
putc(c,stdout);
fgets 和 gets:
fgets 用于從文件流中讀取一行數(shù)據(jù),其原型如下:
char *fgets(char *s, int size, FILE *stream);
◆ s:指向一個(gè)緩沖區(qū),用于存放讀到的數(shù)據(jù)。
◆ size:讀取的字節(jié)數(shù)上限,實(shí)際讀取的字節(jié)數(shù)不會(huì)超過(guò) size-1。
◆ stream:要讀取的文件指針。
◆ 返回值:等于 s,如果有錯(cuò)誤發(fā)生或文件結(jié)束,則返回 NULL。
用 fgets 函數(shù)讀取數(shù)據(jù)時(shí),當(dāng)讀到一個(gè)換行符,或者文件結(jié)束,或者讀取的字節(jié)數(shù)達(dá)到 size-1,則讀取操作不再繼續(xù),函數(shù)返回
。fgets 函數(shù)還會(huì)在讀到的數(shù)據(jù)最后加一個(gè)字符 \0,使之變成一個(gè)合法的字符串。注意,如果讀到換行符,則換行符也在讀到數(shù)據(jù)中。
gets 函數(shù)用于從標(biāo)準(zhǔn)輸入讀取一行數(shù)據(jù),其原型如下:
char *gets(char *s);
參數(shù) s 指向用于存放數(shù)據(jù)的緩沖區(qū),如果讀取成功則返回值就是 s,否則返回 NULL。
gets 是一個(gè)不提倡使用的函數(shù),因?yàn)樗鼘?duì)讀入的字節(jié)數(shù)沒(méi)有控制,緩沖區(qū)是否會(huì)溢出完全取決于用戶(hù)的輸入。
fputs 和 puts:
fputs 函數(shù)用于向文件流寫(xiě)入一個(gè)字符串,其原型如下:
int fputs(cnost char *s, FILE *stream);
◆ s:要寫(xiě)入的字符串,必須是以 \0 結(jié)尾的合法字符串。
◆ stream:要寫(xiě)入的文件指針。
◆ 返回值:非負(fù)數(shù)表示寫(xiě)入成功,有錯(cuò)誤發(fā)生則返回 EOF。
fputs 函數(shù)在向文件流寫(xiě)入字符串時(shí),字符串的結(jié)束符 \0 并不會(huì)被寫(xiě)入。
puts 函數(shù)將字符串寫(xiě)入標(biāo)準(zhǔn)輸出,其原型如下:
int puts(const char *s);
其中 s 參數(shù)是要寫(xiě)入的字符串,它的返回值的含義與 fputs 函數(shù)相同。
與 fputs 函數(shù)不同的是,puts 函數(shù)在將字符串寫(xiě)入之后會(huì)再寫(xiě)入一個(gè)換行符。
fprintf,printf 和 sprintf:
fprintf 是向文件流格式化寫(xiě)入數(shù)據(jù)的函數(shù),其原型如下:
int fprintf(FILE *stream, const char *format,...);
◆ stream:要寫(xiě)入的文件指針。
◆ format:格式字符串。
◆ 可變參數(shù):要寫(xiě)入的數(shù)據(jù)。
◆ 返回值:如果寫(xiě)入成功,則返回格式化后字符串的長(zhǎng)度,也就是寫(xiě)入數(shù)據(jù)的長(zhǎng)度,負(fù)數(shù)表示有錯(cuò)誤發(fā)生。
常用輸出轉(zhuǎn)換符:
格式符 功能
%d 或 %i 按有符號(hào)十進(jìn)制格式輸出整型參數(shù)
%u 按無(wú)符號(hào)十進(jìn)制格式輸出無(wú)符號(hào)整型參數(shù)
%o 按無(wú)符號(hào)八進(jìn)制格式輸出無(wú)符號(hào)整型參數(shù)
%x 按無(wú)符號(hào)十六進(jìn)制格式輸出無(wú)符號(hào)整型參數(shù),使用字母 a,b,c,d,e,f
%X 按無(wú)符號(hào)十六進(jìn)制方式輸出無(wú)符號(hào)整型參數(shù),使用字母 A,B,C,D,E,F
%c 將整型參數(shù)轉(zhuǎn)換為無(wú)符號(hào)字符型,并輸出為字符
%f 按十進(jìn)制格式輸出高精度浮點(diǎn)型參數(shù)
%e 按科學(xué)計(jì)數(shù)法格式輸出高精度浮點(diǎn)型參數(shù),使用字母 e
%E 按科學(xué)計(jì)數(shù)法格式輸出高精度浮點(diǎn)型參數(shù),使用字母 E
%g 或 %G 可理解為系統(tǒng)自帶選擇 %f 或 %e 格式輸出
%p 按十六進(jìn)制格式輸出指針型參數(shù)
%s 將字符指針型參數(shù)視為字符串輸出
因?yàn)楦袷阶址械姆?hào) % 有了特殊的含義,所以要原樣輸出一個(gè) %,則需要連續(xù)寫(xiě)兩個(gè) %,即 %%。
常用輸出格式符標(biāo)志(放在 % 的后面):
字符 作用
數(shù)字 0 當(dāng)輸出數(shù)字時(shí),填充 0 而不是空格
減號(hào) - 修改為左對(duì)齊方式,空格填充在右邊
空格 對(duì)應(yīng)正數(shù)來(lái)說(shuō),左邊預(yù)留一個(gè)空格作為符號(hào)位
加號(hào) + 總是在正數(shù)左邊加上 + 符號(hào),在負(fù)數(shù)左邊加上 - 符號(hào)
我們常用的 printf 函數(shù)實(shí)際上是對(duì) fprintf 函數(shù)的包裝,它用來(lái)向標(biāo)準(zhǔn)輸出寫(xiě)入格式的字符串,其原型如下:
int printf(const char *format, ...);
它比 fprintf 函數(shù)少一個(gè)文件指針參數(shù),因?yàn)檫@個(gè)文件指針一定是 stdout。
與格式化輸出相關(guān)的還有一個(gè)函數(shù) sprintf,它并不是文件 I/O 操作,而是將格式化的字符串輸出到一個(gè)緩沖區(qū)中,原型:
int sprintf(char *str, const char *format, ...);
其中 str 參數(shù)就指向用于存放結(jié)果的緩沖區(qū)。sprintf 函數(shù)會(huì)在輸出字符串的末尾加上結(jié)束符 \0。使用這個(gè)函數(shù)時(shí)要注意,str
指向的緩沖區(qū)要有足夠的大小來(lái)容納生成的字符串,否則就有內(nèi)存訪問(wèn)越界的問(wèn)題。很多情況下并不能事先知道結(jié)果字符串的長(zhǎng)度,這時(shí)可
以用下面這個(gè)函數(shù):
int snprintf(char *str, size_t size, const char *format, ...);
◆ size:限制生成字符串的長(zhǎng)度,即寫(xiě)入緩沖區(qū)的字節(jié)數(shù)。如果格式化后的字符串長(zhǎng)度等于或大于 size,則只寫(xiě)入前 size-1個(gè)
字節(jié),然后寫(xiě)入結(jié)束符 \0。
◆ 返回值:格式化后的字符串長(zhǎng)度。
fscanf,scanf 和 sscanf:
fscanf 可以從文件流以一定的格式讀取數(shù)據(jù),其原型如下:
int fscanf(FILE *stream, const char *format, ...);
◆ stream:要讀取的文件指針。
◆ format:格式字符串。
◆ 可變參數(shù):一般是指針,指向用于存儲(chǔ)到的數(shù)據(jù)流量。
◆ 返回值:成功解析的數(shù)據(jù)項(xiàng)的個(gè)數(shù)(不是字節(jié)數(shù)),失敗則返回 EOF。
格式字符串中的字符將與輸入流中讀到的字符進(jìn)行匹配,具體來(lái)說(shuō)有以下幾種情況。
◆ 空白字符:包括空格、制表、換行等字符,將與輸入流中的連續(xù) 0 個(gè)或多個(gè)空白字符相匹配,也就是說(shuō),一個(gè)空白字符可以消
耗多個(gè)空白字符。
◆ 普通字符:不想與從輸入流讀入的字符相同。
◆ 轉(zhuǎn)換符:以符合 % 開(kāi)始的多個(gè)字符,這時(shí)輸入流中讀入的字符將按某種格式解析為數(shù)據(jù),存入對(duì)應(yīng)的可變參數(shù)指向的變量中。
常用輸入轉(zhuǎn)換符:
轉(zhuǎn)換符 作用
%d 以十進(jìn)制格式讀入整數(shù),存在整型變量中
%i 當(dāng)下一個(gè)字符是 0 時(shí),以八進(jìn)制格式讀取整數(shù);當(dāng)下兩個(gè)字符是 0x 或 0X 時(shí),以十六進(jìn)制格式讀入整數(shù);否則以十進(jìn)制格式讀入整數(shù),存放在整型 變量中。
%u 以十進(jìn)制格式讀入整數(shù),存放在無(wú)符號(hào)整型變量中
%o 以八進(jìn)制格式讀入整數(shù),存放在無(wú)符號(hào)整型變量中
%x 或 %X 以十六進(jìn)制格式讀入整數(shù),存放在無(wú)符號(hào)整型變量中
%f,%g,%e 或 %E 讀入浮點(diǎn)數(shù),存放在浮點(diǎn)型變量中
%s 讀入字符串,字符串從下一個(gè)非空白字符開(kāi)始,再遇到一個(gè)空白字符或者達(dá)到指定的域?qū)捄蠼Y(jié)束。字符串存放在對(duì)應(yīng)的參數(shù)指向的緩沖區(qū)中,末尾會(huì)自 動(dòng)加上 \0
%c 讀入域?qū)捤付▊€(gè)數(shù)的字符,默認(rèn)是一個(gè)。不跳過(guò)開(kāi)始的空白字符,讀入的字符放在對(duì)應(yīng)參數(shù)指向的字符數(shù)組中,末尾不加 \0
scanf 函數(shù)類(lèi)似于 fscnaf 函數(shù),只不過(guò)是從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù),原型:
int scanf(const char *format, ...);
還有一個(gè) sscanf 函數(shù)可以從字符串中格式化讀取數(shù)據(jù),原型:
int sscanf(const char *str, const char *format, ...);
其中,str 參數(shù)就是被讀取的字符串。
標(biāo)準(zhǔn) I/O 錯(cuò)誤處理:
當(dāng)標(biāo)準(zhǔn) I/O 操作發(fā)送錯(cuò)誤時(shí),比如返回 NULL 指針或者 EOF,可以通過(guò)讀 errno 變量得到錯(cuò)誤碼。
更方便的是使用標(biāo)準(zhǔn) I/O 的錯(cuò)誤判斷函數(shù),如:
int ferror(FILE *stream);
int feof(FILE *stream);
ferror 函數(shù)用于判斷文件流是否發(fā)送錯(cuò)誤,若返回非 0 值則表示發(fā)生了錯(cuò)誤。
feof 函數(shù)用于判斷對(duì)文件流的讀寫(xiě)是否已到達(dá)尾部,若返回非 0 值則表示已到達(dá)尾部。
轉(zhuǎn)載于:https://www.cnblogs.com/alionxd/articles/3152455.html
總結(jié)
以上是生活随笔為你收集整理的Linux 标准I/O函数库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 学前班三拼音节教案一等奖
- 下一篇: linux 备份svn