1. fwide函式
用於設定流的定向。
int fwide(file *fp, int mode); //若流是寬定向,返回正值;是位元組定向,返回負值;是未定向,返回0。
如若mode是負值,則函式試圖使指定的流是位元組定向的;如果mode是正值,則函式試圖使制定的流是寬定向的;若mode引數值為0,函式不試圖設定流的定向,返回標識流定向的值。
2. 緩衝
全緩衝,
行緩衝和
不帶緩衝
標準錯誤時不帶緩衝的,開啟至終端裝置的流是行緩衝的,其他流是全緩衝的。
void setbuf(file *restrict fp, char *restrict buf);
用setbuf開啟或者關閉緩衝機制,當buf指向乙個長度為bufsize的緩衝區,在此之後的流就是全緩衝的(對於乙個與終端裝置相關的流,可能不一樣);當buf為null時,代表關閉緩衝。
int setvbuf(file *restrict fp, char *restrict buf, int mode, size_t size);
mode的引數: _iofbf(全緩衝),_iolbf(行緩衝),_ionbf(不帶緩衝)。
int fflush(file *fp); //清洗流,當fp是null時,導致所有的輸出流被清洗
3. 開啟流
fopen,freopen和fdopen。
file *freopen(const char *restrict pathname, const char *restrict type, file *restrict fp);
file *fdopen(int fd, const char *type); //常用於由建立管道和網路通訊通道函式返回的描述符。
4. 讀和寫流
輸入函式:getc,fgetc,getchar。
檔案的尾端或者出錯,呼叫上面的函式,返回都是eof;為了區分這個,呼叫ferror或feof。
int ungetc(int c, file *fp); //從流中讀取資料後,可以呼叫ungetc將字元再壓送回流
輸出函式:putc,fputc,putchar。
5. 每次一行i/o
char *fgets(char *restrict buf, int n, file *restrict fp);
char *gets(char *restrict buf); //不太安全,當輸入長度大於緩衝區長度
對應的輸出函式是fputs和puts。
6. 二進位制i/o
size_t fread(void *restrict ptr, size_t size, size_t nobj, file *restrict fp);
size_t fwrite(const void *restrict ptr, size_t size, size_t nobj, file *restrict fp);
7. 定位流
i. ftell和fseek函式,還有rewind函式可將乙個流設定到檔案的起始位置。
ii. ftello和fseeko函式
iii. fgetpos和fsetpos
8. 格式化i/o
格式化輸出
i. int printf(const char *restrict format, ...);
ii. int fprintf(file *restrict fp, const char *restrict format,);
iii. int dprintf(int fd, const char *restrict format, ...) //寫到指定檔案描述符
ix. int spintf(char *restrict buf, const char *restrict format, ...) //將格式化的字元送入陣列中
x. int snprintf(char *restrict buf, size_t n, const char *restrict format, ...) //跟上面的類似,就是可以控制數量n,防止溢位。
格式化輸入
scanf,fscanf,sscanf函式
9. 實現細節
int fileno(file *fp); //獲得與流相關聯的檔案描述符
測試三種標準流:連線終端輸入流和輸出流都是行緩衝,檔案的輸入輸出流是全緩衝,錯誤的是不帶緩衝的。
#include "apue.h"
void pr_stdio(const char*, file*);
int is_unbuffered(file*);
int is_linebuffered(file*);
int buffer_size(file*);
int main(void)
void pr_stdio(const char* name, file* fp)
#if defined(_io_unbuffered)
int is_unbuffered(file* fp)
int is_linebuffered(file *fp)
int buffer_size(file *fp)
#elif defined(__snbf)
int is_unbuffered(file *fp)
int is_linebuffered(file *fp)
int buffer_size(file *fp)
#elif defined(_ionbf)
#ifdef _lp64
#define _flag __pad[4]
#define _ptr __pad[1]
#define _base __pad[2]
#endif
int is_unbuffered(file *fp)
int is_linebuffered(file *fp)
int buffer_size(file *fp)
#else
#error unknown stdio implementation
#endif
10. 臨時檔案
char *tmpnam(char *ptr); //產生乙個與現有檔名不同的乙個有效路徑名字串
file *tmpfile(void); //建立乙個臨時二進位制檔案,在關閉該檔案或者程式結束時自動刪除這個檔案
#include "apue.h"
int main(void)
相對而言mkstemp更安全一些
char *mkdtemp(char *template); //新建乙個臨時目錄
int *mkstemp(char *template); //新建乙個臨時檔案,返回檔案描述符
#include "apue.h"
#include void make_temp(char *template);
int main()
void make_temp(char *template)
else
}
mkstemp與tmpfile不同,建立的臨時檔案不會自動刪除的。
第一種情況因為使用了陣列,名字是在棧上分配的;但是第二種情況使用的是指標,在這種情況下,只有指標駐留在棧上。編譯器把字串放在了可執行檔案的唯讀段,當mkstemp函式試圖修改字串時,出現了段錯誤。
11. 記憶體流
file *fmemopen(void *retrict buf, size_t size, const char *restrict type); //建立記憶體流
#include "apue.h"
#define bsz 48
int main()
輸出如下:
initial buffer contents:
before flush: //流沖洗後緩衝區才會變化
after flush: hello, world
len of string in buf = 12
after fseek: bbbbbbbbbbbbhello, world//fseek引起緩衝區沖洗
len of string in buf = 24
after fclose: hello, worldcccccccccccccccccccccccccccccccccc
len of string in buf = 46
還有另外兩個函式
file *open_memstream(char **bufp, size_t *sizep); //建立的流是面向位元組的
file *open_wmemstream(wchar_t **bufp, size_t *sizep); //建立的流是面向寬位元組的
p173
第五章 標準I O庫
本章用於解析c語言標準i o庫,之所以在unix類系統的程式設計中會介紹c語言標準庫,主要是因為unix和c之間具有密不可分的關係。標準i o庫相比於作業系統的i o庫,具有更高的效率和可移植性,前者是因為標準i o庫提供了緩衝和塊長度優化功能,後者是因為使用標準i o庫的 不僅能在各unix系統上...
APUE筆記 第五章 標準I O庫
2.流和相關函式 3.格式化i o 4.fileno 函式 5.tmpnam 和tmpfile 函式 標準i o庫是在系統呼叫函式基礎上構造的。ansi c要求下列快取特徵 1 當且僅當標準輸入和標準輸出並不涉及互動作用裝置時,它們才是全快取的。2 標準出錯決不會是全快取的。1.1全快取 在這種情況...
python第五章 Python學習(第五章)
記錄所有的名片字典 card list defshow menu 顯示資訊 print 50 print 歡迎使用 名片管理系統 v1.0 print print 1.新增名片 print 2.顯示全部 print 3.搜尋名片 print print 0.退出系統 print 50 defnew ...