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