FILE *
進(jìn)行的,稱其為文件指針
。FILE對(duì)象通常是一個(gè)結(jié)構(gòu),它包括了標(biāo)準(zhǔn)I/O庫為管理該流需要的所有信息,包括用于實(shí)際I/O的文件描述符、指向用于該流緩沖區(qū)的指針、緩沖區(qū)的長度、當(dāng)前在緩沖區(qū)中的字符數(shù)以及出錯(cuò)標(biāo)志等。
標(biāo)準(zhǔn)I/O文件流可用于單字節(jié)或多字節(jié)(“寬”)字符集。
寬定向
的;若在為定向的流上使用一個(gè)單字節(jié)I/O函數(shù),則將流的定向設(shè)置為字節(jié)定向
的。#include <stdio.h>
#include <wchar.h>
int fwide(FILE *fp, int mode);
Returns: positive if stream is wide oriented,
negative if stream is byte oriented,
or 0 if stream has no orientation
- mode為負(fù),則字節(jié)定向;
- mode為正,則寬定向;
- mode為0,則不設(shè)置流的定向,fwide返回標(biāo)識(shí)該流定向的值
標(biāo)準(zhǔn)I/O庫提供緩沖的目的是盡可能減少使用read和write調(diào)用的次數(shù)。它對(duì)每個(gè)I/O流自動(dòng)地進(jìn)行緩沖管理,從而避免了應(yīng)用程序需要考慮這一點(diǎn)所帶來的麻煩。遺憾的是,標(biāo)準(zhǔn)I/O庫最令人迷惑的也是它的緩沖。
標(biāo)準(zhǔn)I/O提供了以下3種類型的緩沖:
- 全緩沖。在填滿標(biāo)準(zhǔn)I/O緩沖區(qū)后才進(jìn)行實(shí)際I/O操作。對(duì)于駐留在磁盤上的文件通常由標(biāo)準(zhǔn)I/O庫實(shí)施全緩沖。緩沖區(qū)可由標(biāo)準(zhǔn)I/O例程自動(dòng)地沖洗(flush),也可通過調(diào)用函數(shù)fflush沖洗一個(gè)流。
- 術(shù)語flush有兩種意思:在標(biāo)準(zhǔn)I/O庫方面,flush(沖洗)意味著緩沖區(qū)中的內(nèi)容寫到磁盤上;在終端驅(qū)動(dòng)程序方面,flush(刷清)表示丟棄已存儲(chǔ)在緩沖區(qū)中的數(shù)據(jù)。
- 行緩沖。當(dāng)輸入或輸出中遇到換行符時(shí),標(biāo)準(zhǔn)I/O庫執(zhí)行I/O操作。當(dāng)流涉及一個(gè)終端時(shí),通常使用行緩沖。
- 對(duì)于行緩沖有兩個(gè)限制:
- 只要填滿了緩沖區(qū),即使還沒遇到換行符,也進(jìn)行I/O操作;
- 任何時(shí)候只要通過標(biāo)準(zhǔn)I/O庫要求從(a)
一個(gè)
不帶緩沖的流,或者(b)一個(gè)
行緩沖的流得到輸入數(shù)據(jù),那么就會(huì)flush所有
行緩沖輸出流。- 不帶緩沖。標(biāo)準(zhǔn)I/O庫不對(duì)字符進(jìn)行緩沖存儲(chǔ)。如fputs函數(shù)。標(biāo)準(zhǔn)錯(cuò)誤流stderr通常是不帶緩沖的。
ISO C要求下列緩沖特征:
- 當(dāng)且僅當(dāng)標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出并不指向交互式設(shè)備時(shí),它們才是全緩沖的
- 標(biāo)準(zhǔn)錯(cuò)誤決不會(huì)是全緩沖的
很多系統(tǒng)默認(rèn)使用下列類型的緩沖:
- 標(biāo)準(zhǔn)錯(cuò)誤是不帶緩沖的
- 若是指向終端設(shè)備的流,則是行緩沖的;否則是全緩沖的
#include <stdio.h>
void setbuf(FILE *restrict fp, char *restrict buf );
// 使用該函數(shù)打開或關(guān)閉緩沖機(jī)制。參數(shù)buf必須指向一個(gè)長度為BUFSIZ的緩沖區(qū);或?yàn)镹ULL以關(guān)閉緩沖
int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);
Returns: 0 if OK, nonzero on error
#include <stdio.h>
int fflush(FILE *fp); // 若fp為NULL,則導(dǎo)致所有輸出流被沖洗
Returns: 0 if OK, EOF on error
#include <stdio.h>
FILE *fopen(const char *restrict pathname, const char *restrict type);
FILE *freopen(const char *restrict pathname, const char *restrict type, FILE *restrict fp);
// 在一個(gè)指定的流上打開一個(gè)指定的文件,如若該流已經(jīng)打開,則先關(guān)閉該流
FILE *fdopen(int fd, const char *type); // 取一個(gè)已有的文件描述符,并使一個(gè)標(biāo)準(zhǔn)的I/O流與該描述符相結(jié)合
All three return: file pointer if OK, NULL on error
如果以讀和寫類型打開一個(gè)文件時(shí)(type中帶+號(hào)),具有下列限制:
- 如果中間沒有fflush、fseek、fsetpos或rewind,則在輸出的后面不能直接跟隨輸入
- 如果中間沒有fseek、fsetpos或rewind,或者一個(gè)輸入操作沒有到達(dá)文件尾端,則在輸入操作之后不能直接跟隨輸出
打開一個(gè)標(biāo)準(zhǔn)I/O流的6種不同方式
#include <stdio.h>
int fclose(FILE *fp);
Returns: 0 if OK, EOF on error
一旦打開了流,可在3種
不同類型的非格式化I/O中進(jìn)行選擇,對(duì)其進(jìn)行讀、寫操作
- 每次一個(gè)字符的I/O
- 每次一行的I/O
- 直接I/O(二進(jìn)制I/O、面向記錄的I/O、一次一個(gè)對(duì)象的I/O)
在大多數(shù)實(shí)現(xiàn)中,為每個(gè)流在FILE對(duì)象中維護(hù)了兩個(gè)標(biāo)志:
- 出錯(cuò)標(biāo)志
- 文件結(jié)束標(biāo)志
區(qū)分是出錯(cuò)還是到達(dá)文件尾端,因?yàn)檫@兩種情況下返回值相同
#include <stdio.h>
int ferror(FILE *fp);
int feof(FILE *fp);
Both return: nonzero (true) if condition is true, 0 (false) otherwise
void clearerr(FILE *fp); // 調(diào)用clearerr可以清除這兩個(gè)標(biāo)志
#include <stdio.h>
int getc(FILE *fp); // 可被實(shí)現(xiàn)為宏,故參數(shù)不應(yīng)當(dāng)是具有副作用的表達(dá)式;返回值是int,因?yàn)槌A縀OF是-1
int fgetc(FILE *fp); // 一定是個(gè)函數(shù)
新聞熱點(diǎn)
疑難解答
圖片精選