標準I/O庫
阿新 • • 發佈:2018-12-16
tel 下一個 相關 chat 寫入 使用 進制 set lose
僅當標準輸入和標準輸出並不指向交互式設備時,他們才是全緩沖
標準錯誤不會是全緩沖
一般情況下,標準錯誤不帶緩沖,指向終端的流為行緩沖,其他為全緩沖
設置流的定向:
#include <stdio.h> #include <wchar.h> // 流的定向決定了所讀、寫的字符是單字節(字節定向)還是多字節的(寬定向) // 若流是寬定向的返回正值,若流是字節定向的返回負值,若流未定向,返回0 int fwide(FILE *fp, int mode); // fp: 與要被設置流的定向的文件相關的流 // mode取值決定fwide()如何工作: // mode為正,指定為寬定向;mode為負,指定為字節定向;mode為0,不做任何設置,僅僅返回標識該流的定向
緩沖區操作:
緩沖類型:
全緩沖:在填滿I/O緩沖區後才進行實際的I/O操作
行緩沖:在I/O中遇到換行符時,標準I/O庫才執行I/O操作
行緩沖的限制是無法得知在執行實際的I/O操作時是因為換行符還是其他原因
不帶緩沖:標準I/O庫不對字符進行緩沖存儲
ISO C要求的緩沖特征:
僅當標準輸入和標準輸出並不指向交互式設備時,他們才是全緩沖
標準錯誤不會是全緩沖
一般情況下,標準錯誤不帶緩沖,指向終端的流為行緩沖,其他為全緩沖
#include <stdio.h> // 成功返回0,出錯返回-1 void setbuf(FILE *fp, char *buf); // fp是一個打開著的,與將被操作的文件相關的流 // buf指向一個長度為BUFSIZ的緩沖區或者為NULL // 當buf為NULL時表示關閉緩沖機制 // 當buf不為NULL時,表示打開緩沖機制,但具體是何種緩沖取與fp相關 void setvbuf(FILE *fp, char *buf, int mode, size_t size);// setvbuf()可以精確設置所需的緩沖類型 // mode為 _IOFBF為全緩沖 // mode為 _IOLBF為行緩沖 // mode為 _IONBF為不帶緩沖,此時忽略buf和size參數 // buf和size用於指定一個緩沖區及其長度 // 若buf為NULL,但該流帶緩沖,則緩沖區由標準I/O庫分配,長度為BUFSIZ // 強制沖洗一個緩沖區 int fflush(FILE *fp);
流的打開與關閉:
#include <stdio.h> // 成功返回文件指針,出錯返回NULL FILE *fopen(const char *path, const char *type); // path指定被打開的文件路徑// type指定對該I/O流的讀寫方式 FILE *freopen(const char *path, const char *type, FILE *fp); // 在一個指定的流(fp)上打開一個文件,若該流已經打開,則先關閉該流,若該流已經定向,則清除該定向 FILE *fdopen(int fd, const char *type); // 為一個現有的文件描述符(fd)打開一個相關的流,一般用於那寫無法用fopen()打開的特殊文件 // 成功返回0,出錯返回EOF int fclose(FILE *fp); // 關閉一個打開著的流
對流進行讀寫:
#include <stdio.h> // 一次讀取一個字符 // 成功返回下一個字符,出錯或到達文件尾端,返回EOF int getc(FILE *fp); int fgetc(FILE *fp); int getchar(); // 關於返回值問題: // 由於在<stdio.h>中的常量EOF被要求是一個負值,且其值經常為-1,不論是出錯還是到達文件 // 尾端,他們的返回值都一樣,所以為了區分這兩種情況,必須調用ferror()、feof() // 將一個字符壓送回流緩沖區 // 成功返回c,出錯返回EOF int ungetc(int c, FILE (fp); // 向指定流寫入一個字符 // 成功返回c,出錯返回EOF int putc(int c, FILE *fp); int fputc(int c, FILE *fp); int putchar(int c); // 每次從指定流讀取一行 // 成功返回buf,出錯返回NULL char *fgets(char *buf, int n, FILE *fp); // n為buf長度 char *gets(char *buf); // 棄用,可能造成緩沖區溢出 // 向指定流輸出一行 // 成功返回非負值,出錯返回EOF int fputs(const char *str, FILE *fp); int puts(const char *str); // 二進制I/O: // 返回讀、寫的對象數 size_t fread(void *ptr, size_t size, size_t nobj, FILE *fp); size_t fwrite(const void *ptr, size_t size, size_t nobj, FILE *fp); // nobj 為將被讀寫的對象個數
對流進行定位:
#include <stdio.h> // 成功返回當前文件位置,出錯返回-1 long ftell(FILE *fp); off_t ftello(FILE *fp); // 設置文件偏移量 // 成功返回0,出錯返回-1 int fseek(FILE *fp, long offset, int whence); int fseeko(FILE *fp, off_t offset, int whence); void rewind(FILE *fp); // 獲取、設置文件位置 // 成功返回0,出錯返回-1 int fgetpos(FILE *fp, fpos_t *pos); int fsetpos(FILE *fp, fpos_t *pos); // pos用於存放文件位置指示器的值
創建臨時文件:
#include <stdio.h> // 返回指向唯一路徑名的指針 char *tmpnam(char *ptr); // ptr為NULL時,該路徑名存放在一個靜態區中 // ptr不為NULL時,則認為它是指向長度至少是L_tmpnam個字符的數組 // 一般在程序中使用時,使用tmpnam()返回的路徑值創建一個文件,並對它使用unlink() // 創建一個臨時二進制文件,在關閉該文件或程序結束時自動刪除此文件 // 成功返回文件指針,出錯返回NULL FILE *tmpfile(void); // SUS為處理臨時文件定義的函數 #include <stdlib.h> // 成功返回指向目錄名的指針,出錯返回NULL char *mkdtemp(char *template); // 成功返回文件描述符,出錯返回-1 int mkstemp(char *template); // 名字是通過template字符串選擇的,template是的後6位被設置為XXXXXX路徑名
內存流:
#include <stdio.h> #include <wchar.h> // 打開一個內存流 // 成功返回流指針,出錯返回NULL FILE *fmemopen(void *buf, size_t size, const chat *type); // buf指向緩沖區開始位置,size指定緩沖區大小,type指定如何使用流,類似用打開文件時的type FILE *open_memstream(char **bufp, size_t *sizep); // 創建的流面向字節的 FILE *open_wmemstream(wchar_t **bufp, size_t *sizep); // 創建的流面向寬字節 // 通過bufp、sizep返回緩沖區地址和大小 // 限制:創建的流只能打開,且不能自己指定緩沖區,關閉流後需要自行釋放緩沖區,對流添加字節會增加緩沖區大小
標準I/O庫