5.1 標準i/o由dennis ritchie在2023年左右編寫。
5.2 第三章的i/o都是針對檔案描述符。而標準i/o庫是圍繞stream,開啟或建立檔案時,我們已經使乙個stream與檔案相關聯。
stream的定向決定了讀寫的字元是單字元還是多位元組。在未定向的流上使用i/o函式可以改變定向。只有兩個函式可以改變流定向。freopen用來清除stream的定向。
int fwide(file *fp, int mode); mode 負數 試圖指定位元組定向。 正值,試圖指定寬定向。 0,不設定,返回當前的定向值。
5.3 檔案描述符stdin_fileno, stdout_fileno, stderr_fileno分別和stdin,stdout,stderr引用的檔案是相同的。
前者#include 中,字尾定義在#include 中。
5.4 標準i/o提供緩衝的目的是減少讀寫的呼叫次數。
1)全緩衝。填滿標準i/o緩衝區才進行實際i/o操作。常見的是磁碟上的檔案。可以呼叫fflush(寫入),tcflush(丟棄)現有緩衝內容。
2)行緩衝。輸入和輸出中遇到換行符時,標準i/o庫執行i/o操作。a>長度固定,滿了就i/o操作。b>標準i/o庫要求從「不帶緩衝」或「帶行緩衝」的流中得到輸入資料,則會執行。
3)不帶緩衝。標準i/o庫不對字元進行緩衝儲存。如fputs函式。標準stderr通常不帶緩衝。
iso c要求下列緩衝特徵:
#當且僅當stdin和stdout不涉及互動device,才是full緩衝。
#stderr絕不是full緩衝。
很多預設系統:
#stderr不是帶緩衝的。
#涉及到terminal裝置的其他stream,是line緩衝。否則是full緩衝。
void setbuf(file *restrict fp, char *restrict buf);開啟或關閉緩衝機制。
int setvbuf(file *restrict fp, char *restrict buf, int mode, size_t size);
int fflush(file *fp);強制flush乙個steam,該流所有未write的資料都被傳送至核心。如果fp為null,則所有輸出流被flush。
詳細情況看下圖
5.5 開啟乙個標準流。
file *fopen(const char *restrict pathname, const char *restrict type);開啟指定流。
file *freopen(const char *restrict pathname, const char* restrict type, file *restrict fp);
在指定流開啟指定檔案。如流已開啟,則先關閉。如已定向,則清除定向。一般用於將指定檔案開啟為stdin,stdout或stderr。
file *fdopen(int filedes, const char *type);使標準i/o流與檔案描述符相結合。filedes通常是建立「管道」和「網路通訊通道」函式的返回值。(posix.1專有)
開啟模式見下圖
int fclose(file *fp);關閉開啟的流。關閉前,會flush緩衝區中的output資料。丟棄任何input資料。
5.6 一旦開啟流,可以在三種不同type的非格式化i/o中進行選擇,對其read,write。
1)每次乙個字元i/o。
輸入:int getc(file *fp);
int fgetc(file *fp);
int getchar(void);等價於getc(stdin)。
不管是出錯還是eof,三個函式返回同樣的值,為了區分。比如呼叫:
int ferror(file *fp);
int feof(file *fp);
void clearerr(file *fp);大多數實現中,每個流在file物件中維持了a)出錯標誌。b)eof標誌。此函式可以清除這兩個標誌。
int ungetc(int c, file *fp);從流中讀取資料後,可以呼叫此函式將字元再壓送回流中。
輸出:int putc(int c, file *fp);
int fputc(int c, file *fp);
int putchar(int c);等價於putc(c, stdout)。
2)每次一行的i/o。fgets,fputs
3)直接i/o。fread,fwrite。
5.7 每次一行i/o。
輸入:char *fgets(char *restrict buf, int n, file *restrict fp);從流中讀取n-1個字元。
char *gets(char *buf);從stdin中讀取,不會講換行符存入緩衝區,不推薦使用。
輸出:int fputs(const char *restrict str, file *restrict fp);將null結尾的字串寫到指定流。結尾的null不寫出。不一定每次輸出一行,遇到null就停止。
int puts(const char *str);將null結尾的寫到stdout,null不寫。但是puts由將乙個換行符寫到stdout。不推薦使用。
5.8 標準i/o庫與直接呼叫read,write函式相比並不慢多少。
5.9 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);
常見的用法:1)讀或寫乙個二進位制陣列。比如:
float data[10]; fwrite(&data[2], sizeof(float), 4, fp);寫2-5元素到檔案上。
2)讀或寫乙個結構。
5.10 定位流有三種方法。
1)ftell和fseek。都假定檔案的位置可以存放在乙個long中。
2)ftello和fseeko。single unix specification引入的。使用off_t代替了long。
3)fgetpos和fsetpos。由iso c引入。使用抽象資料型別fpos_t記錄檔案位置。
5.11 格式化輸出
printf, fprintf, sprintf, snprintf.
vprintf, vfprintf, vsprintf, vsnprintf.可變引數。
格式化輸入
scanf, fscanf, sscanf.
5.12 對於stream可以用int fileno(file *fp);來獲取其檔案描述符。
fp->_io_file_flags &_io_unbuffered等等。如有buffer,大小為fp->_io_buf_end - fp->_io_buf_base;
5.13 建立臨時檔案。
char *tmpnam(char *ptr);最多呼叫次數tmp_max。
file *tmpfile(void);建立臨時二進位制檔案(型別wb+),關閉檔案或程式結束自動被刪除。
char *tempnam(const char *directory, const char *prefix);xsi擴充套件,非iso c。
int mkstemp(char *template);xsi擴充套件,非iso c。
5.14 標準i/o效率不高。可以替代它的版本有sfio(korn & vo[1991])。krieger,stunmm & unrau[1992]使用對映檔案--mmap函式。
許多標準i/o庫實現可用於c函式庫中。兩種實現是uclibc c庫,以及newlibc庫。
5.15 大多數unix應用程式都使用標準i/o庫。
UNIX環境高階程式設計第二版 讀書筆記6章
6.1 由於歷史原因,大量系統有關的資料檔案都是ascii文字檔案。6.2 口令檔案中shell如果為 dev null表示阻止任何人以該使用者名義登陸。finger p username可以顯示使用者相關資訊。有些系統提供了vipw命令,允許管理員編輯口令檔案。獲取口令檔案項的函式。struct ...
修改《Unix環境高階程式設計第二版》程式清單4 7
修改了 unix環境高階程式設計第二版 程式清單4 7,使用chdir變換當前工作目錄,使用檔案名字而不是檔案路徑進行處理。通過測試,執行效率提高了。測試環境為centos 6.5 include apue.h include stdio.h include fcntl.h include unis...
UNIX環境高階程式設計 第二章
這一節介紹了三個重要的標準 由於c語言在unix系統中的地位不言而喻,c語言的標準化也是unix標準化的重要組成部分。iso c標準當中包括了 時間線 1989 發布 1999 更新 2001 2004 2007 勘誤 2011 更新 posix portable operating system ...