Linux 标准I/O函数库
標準I/O函數庫:
C標準庫提供了文件的標準 I/O 函數庫,相比前述的系統調用,主要差別是實現了跨平臺的用戶態緩沖的解決方案。標準I/O庫使
用簡單,與系統調用I/O相似,也包括打開、讀寫、關閉這些操作,主要的函數列舉如下。
◆ 打開與關閉文件:fopen,fclose。
◆ 讀寫文件:fread,fwrite。
◆ 讀寫文本行:fgets,fputs。
◆ 格式化讀寫:fscanf,fprintf。
◆ 標準輸入輸出:printf,scanf。
◆ 讀寫字符:fgetc,getc,getchar,fputc,putc,putchar。
◆ 其他:fflush,fseek。
所謂標準 I/O 函數實際上是對底層系統調用的包裝,最終讀寫設備或文件的操作仍需調用系統I/O函數來完成。
兩個重要的概念:文件指針和流。
標準I/O函數并不直接操作文件描述符,而是使用文件指針。文件指針與文件描述符是一一對應的關系,這種對應關系由標準I/O庫
自己內部維護。應用程序調用時,只需要提供文件指針即可。文件指針指向的數據類型為FILE型,但應用程序無須關系它的具體內容。
在標準I/O中,一個打開的文件稱為流(stream),流可以用于讀(輸入流)、寫(輸出流)或者是讀寫(輸入輸出流)。每個進
程在啟動后就會打開三個流,與打開的三個文件相對應:stdin代表標準輸入流,stdout代表標準輸出流,stderr代表標準錯誤輸出流,它
們都是(FILE*)型的指針。
標準錯誤輸出流不進行緩沖,輸出的內容會馬上同步到文件(控制臺設備)。
與標準 I/O 相關的定義和聲明都放在以下頭文件中:#include <stdio.h>
fopen:
fopen函數用于打開一個文件流,其原型如下:
FILE *fopen(const char *filename, const char *mode);
◆ filename:被打開的文件的名稱(可包含路徑)。
◆ mode:字符串,用于表示打開的模式。
◆ 返回值:打開成功后的文件指針,失敗則返回NULL。
mode如下:
字符串 含義
r 或 rb 以只讀方式打開
w 或 wb 以只寫方式打開,若文件有內容,則清空
a 或 ab 以只寫方式打開,原內容保留,寫入的內容附加在文件流尾部
r+ 或 rb+ 或 r+b 以更新方式打開,此時文件可讀可寫
w+ 或 wb+ 或 w+b 以更新方式打開,文件可讀可寫,但打開時清空文件內容
a+ 或 ab+ 或 a+b 以更新方式打開,文件可讀可寫,寫入的內容附加在文件流尾部
fread 和 fwrite:
fread函數用于從打開的文件流中讀數據,其原型如下:
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
◆ ptr:指向用于存放讀取到的數據的緩沖區。
◆ size:被讀取的數據塊的長度。
◆ nitems:要讀取的數據塊的個數。
◆ stream:被讀取的文件指針。
◆ 返回值:實際讀取到的數據塊的個數。
使用 fread 函數需要注意的是,它以數據塊(或稱記錄)為單位進行讀取,返回值也是成功讀取的數據塊的個數,而不是字節數
,這個數目有可能比要讀取的個數 nitems 少。
fwrite 函數用于向打開的文件流寫入數據,其原型如下:
size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream);
◆ ptr:指向存放寫入數據的緩沖區。
◆ size:要寫入的數據塊的長度。
◆ nitems:要寫入的數據塊的個數。
◆ stream:要寫入的文件指針。
◆ 返回值:實際寫入的數據塊的個數。
與 fread 函數類似,fwrite 函數也是數據塊為單位向文件流寫入數據的。
fclose:
fclose 函數用于關閉文件,其原型如下:
int fclose(FILE *stream);
這個函數可以改變 stream 參數所代表的文件,如果改變成功則返回 0,否則將返回 EOF 并且設置變量 errno 的值以指示錯誤。
改變前會自動將文件流中的數據寫入文件。
fflush:
fflush 函數用于將文件流中的數據更新到真實的文件中,其原型如下:
int fflush(FILE *stream);
其中參數 stream 是要操作的文件指針,如果更新成功則返回 0,否則將返回 EOF 并且設置變量 errno 的值以指示錯誤。
在用 fclose 關閉文件前,系統會自動調用 fflush 更新數據。
fseek 和 ftell:
fseek 用于移動文件流的讀寫位置,其原型如下:
int fseek(FILE *stream, long offset, int whence);
◆ stream:被操作的文件指針。
◆ offset:讀寫位置的偏移量。
◆ whence:用于指定偏移量的相對啟點。
◆ 返回值:0 表示操作成功, -1 表示操作失敗并且設置 errno 變量的值為錯誤碼。
whence 參數的取值及含義:
◆ SEEK_SET:表示偏移量相對于文件的開頭。
◆ SEEK_CUR:表示偏移量相對于當前的讀寫位置。
◆ SEEK_END:表示偏移量相對于文件末尾。
如果要將讀寫位置移動到文件的開頭,還可以使用這個函數:
void rewind(FILE *stream);
ftell 函數可以得到文件流的讀寫位置,其原型:
long ftell(FILE *stream);
參數 stream 是文件指針,返回值就是文件流的當前讀寫位置(相對于文件開頭)。
fgetc,getc,getchar:
fgetc 函數用于從文件流中讀取一個字符,其原型如下:
int fgetc(FILE *stream);
與它功能相同的函數時 getc,原型如下:
int getc(FILE *stream);
其中 stream 參數是要讀取的文件流。它們返回值雖然是整型,但實際表示的是讀到的字符,只不過進行了類型轉換。如果讀操作
發送錯誤或者到達文件尾,則返回值是 EOF。
getc 與 fgetc 的區別在于它可能是由宏定義實現的,因此參數可能在宏展開以后被使用多長,如果參數本身是一個表達式就會被
多長求值,這種情況在使用中應該避免。
getchar 函數用于從標準輸入流讀取一個字符,其原型如下:
int getchar(void);
實際上對 getchar 的調用完成等價于一下函數的調用:
getc(stdin);
fputc,putc 和 putchar:
fputc 函數用于向文件流寫入一個字符,其原型如下:
int fputc(int c, FILE *stream);
putc 函數與它的功能相同:
int putc(int c, FILE *stream);
◆ c:是要寫入的字符,它雖然是整型,但寫入時會將其轉換為無符號字符型。
◆ stream:要寫入的文件指針。
◆ 返回值:寫入的字符轉換成整型后的值,發送錯誤則返回 EOF。
putc 函數與fputc函數的區別在于它有可能是用宏定義實現的。
putchar 用于向標準輸出寫入一個字符:
int putchar(int c);
與putc等同:
putc(c,stdout);
fgets 和 gets:
fgets 用于從文件流中讀取一行數據,其原型如下:
char *fgets(char *s, int size, FILE *stream);
◆ s:指向一個緩沖區,用于存放讀到的數據。
◆ size:讀取的字節數上限,實際讀取的字節數不會超過 size-1。
◆ stream:要讀取的文件指針。
◆ 返回值:等于 s,如果有錯誤發生或文件結束,則返回 NULL。
用 fgets 函數讀取數據時,當讀到一個換行符,或者文件結束,或者讀取的字節數達到 size-1,則讀取操作不再繼續,函數返回
。fgets 函數還會在讀到的數據最后加一個字符 \0,使之變成一個合法的字符串。注意,如果讀到換行符,則換行符也在讀到數據中。
gets 函數用于從標準輸入讀取一行數據,其原型如下:
char *gets(char *s);
參數 s 指向用于存放數據的緩沖區,如果讀取成功則返回值就是 s,否則返回 NULL。
gets 是一個不提倡使用的函數,因為它對讀入的字節數沒有控制,緩沖區是否會溢出完全取決于用戶的輸入。
fputs 和 puts:
fputs 函數用于向文件流寫入一個字符串,其原型如下:
int fputs(cnost char *s, FILE *stream);
◆ s:要寫入的字符串,必須是以 \0 結尾的合法字符串。
◆ stream:要寫入的文件指針。
◆ 返回值:非負數表示寫入成功,有錯誤發生則返回 EOF。
fputs 函數在向文件流寫入字符串時,字符串的結束符 \0 并不會被寫入。
puts 函數將字符串寫入標準輸出,其原型如下:
int puts(const char *s);
其中 s 參數是要寫入的字符串,它的返回值的含義與 fputs 函數相同。
與 fputs 函數不同的是,puts 函數在將字符串寫入之后會再寫入一個換行符。
fprintf,printf 和 sprintf:
fprintf 是向文件流格式化寫入數據的函數,其原型如下:
int fprintf(FILE *stream, const char *format,...);
◆ stream:要寫入的文件指針。
◆ format:格式字符串。
◆ 可變參數:要寫入的數據。
◆ 返回值:如果寫入成功,則返回格式化后字符串的長度,也就是寫入數據的長度,負數表示有錯誤發生。
常用輸出轉換符:
格式符 功能
%d 或 %i 按有符號十進制格式輸出整型參數
%u 按無符號十進制格式輸出無符號整型參數
%o 按無符號八進制格式輸出無符號整型參數
%x 按無符號十六進制格式輸出無符號整型參數,使用字母 a,b,c,d,e,f
%X 按無符號十六進制方式輸出無符號整型參數,使用字母 A,B,C,D,E,F
%c 將整型參數轉換為無符號字符型,并輸出為字符
%f 按十進制格式輸出高精度浮點型參數
%e 按科學計數法格式輸出高精度浮點型參數,使用字母 e
%E 按科學計數法格式輸出高精度浮點型參數,使用字母 E
%g 或 %G 可理解為系統自帶選擇 %f 或 %e 格式輸出
%p 按十六進制格式輸出指針型參數
%s 將字符指針型參數視為字符串輸出
因為格式字符串中的符號 % 有了特殊的含義,所以要原樣輸出一個 %,則需要連續寫兩個 %,即 %%。
常用輸出格式符標志(放在 % 的后面):
字符 作用
數字 0 當輸出數字時,填充 0 而不是空格
減號 - 修改為左對齊方式,空格填充在右邊
空格 對應正數來說,左邊預留一個空格作為符號位
加號 + 總是在正數左邊加上 + 符號,在負數左邊加上 - 符號
我們常用的 printf 函數實際上是對 fprintf 函數的包裝,它用來向標準輸出寫入格式的字符串,其原型如下:
int printf(const char *format, ...);
它比 fprintf 函數少一個文件指針參數,因為這個文件指針一定是 stdout。
與格式化輸出相關的還有一個函數 sprintf,它并不是文件 I/O 操作,而是將格式化的字符串輸出到一個緩沖區中,原型:
int sprintf(char *str, const char *format, ...);
其中 str 參數就指向用于存放結果的緩沖區。sprintf 函數會在輸出字符串的末尾加上結束符 \0。使用這個函數時要注意,str
指向的緩沖區要有足夠的大小來容納生成的字符串,否則就有內存訪問越界的問題。很多情況下并不能事先知道結果字符串的長度,這時可
以用下面這個函數:
int snprintf(char *str, size_t size, const char *format, ...);
◆ size:限制生成字符串的長度,即寫入緩沖區的字節數。如果格式化后的字符串長度等于或大于 size,則只寫入前 size-1個
字節,然后寫入結束符 \0。
◆ 返回值:格式化后的字符串長度。
fscanf,scanf 和 sscanf:
fscanf 可以從文件流以一定的格式讀取數據,其原型如下:
int fscanf(FILE *stream, const char *format, ...);
◆ stream:要讀取的文件指針。
◆ format:格式字符串。
◆ 可變參數:一般是指針,指向用于存儲到的數據流量。
◆ 返回值:成功解析的數據項的個數(不是字節數),失敗則返回 EOF。
格式字符串中的字符將與輸入流中讀到的字符進行匹配,具體來說有以下幾種情況。
◆ 空白字符:包括空格、制表、換行等字符,將與輸入流中的連續 0 個或多個空白字符相匹配,也就是說,一個空白字符可以消
耗多個空白字符。
◆ 普通字符:不想與從輸入流讀入的字符相同。
◆ 轉換符:以符合 % 開始的多個字符,這時輸入流中讀入的字符將按某種格式解析為數據,存入對應的可變參數指向的變量中。
常用輸入轉換符:
轉換符 作用
%d 以十進制格式讀入整數,存在整型變量中
%i 當下一個字符是 0 時,以八進制格式讀取整數;當下兩個字符是 0x 或 0X 時,以十六進制格式讀入整數;否則以十進制格式讀入整數,存放在整型 變量中。
%u 以十進制格式讀入整數,存放在無符號整型變量中
%o 以八進制格式讀入整數,存放在無符號整型變量中
%x 或 %X 以十六進制格式讀入整數,存放在無符號整型變量中
%f,%g,%e 或 %E 讀入浮點數,存放在浮點型變量中
%s 讀入字符串,字符串從下一個非空白字符開始,再遇到一個空白字符或者達到指定的域寬后結束。字符串存放在對應的參數指向的緩沖區中,末尾會自 動加上 \0
%c 讀入域寬所指定個數的字符,默認是一個。不跳過開始的空白字符,讀入的字符放在對應參數指向的字符數組中,末尾不加 \0
scanf 函數類似于 fscnaf 函數,只不過是從標準輸入讀取數據,原型:
int scanf(const char *format, ...);
還有一個 sscanf 函數可以從字符串中格式化讀取數據,原型:
int sscanf(const char *str, const char *format, ...);
其中,str 參數就是被讀取的字符串。
標準 I/O 錯誤處理:
當標準 I/O 操作發送錯誤時,比如返回 NULL 指針或者 EOF,可以通過讀 errno 變量得到錯誤碼。
更方便的是使用標準 I/O 的錯誤判斷函數,如:
int ferror(FILE *stream);
int feof(FILE *stream);
ferror 函數用于判斷文件流是否發送錯誤,若返回非 0 值則表示發生了錯誤。
feof 函數用于判斷對文件流的讀寫是否已到達尾部,若返回非 0 值則表示已到達尾部。
轉載于:https://www.cnblogs.com/alionxd/articles/3152455.html
總結
以上是生活随笔為你收集整理的Linux 标准I/O函数库的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学前班三拼音节教案一等奖
- 下一篇: TP-Link TL-WDR6600 无