Linux C: IO库函数,文件流缓冲,变参函数
一、I/O 庫函數與系統調用
? ? ? 在Linux 中有很多關于IO(輸入輸出)的庫函數,其大部分都存在 stdio.h 頭文件中。例如fopen,fread,fwrite,fseek,fclose , 這些都是針對文件的,這些函數分別依賴于系統調用open,read,write,lseek,close
其中fopen的第二個參數”打開模式“的說明如下:
r , w ,a ,+, b,t? ?分別表示 讀、寫(清空內容)、讀寫、追加、二進制文件、文本文件
| 字符串(char * ) | 說明 |
| r | 以只讀方式打開文件,該文件必須存在。 |
| r+ | 以讀/寫方式打開文件,該文件必須存在。 |
| rb+ | 以讀/寫方式打開一個二進制文件,只允許讀/寫數據。 |
| rt+ | 以讀/寫方式打開一個文本文件,允許讀和寫。 |
| w | 打開只寫文件,若文件存在則文件長度清為零,即該文件內容會消失;若文件不存在則創建該文件。 |
| w+ | 打開可讀/寫文件,若文件存在則文件長度清為零,即該文件內容會消失;若文件不存在則創建該文件。 |
| a | 以附加的方式打開只寫文件。若文件不存在,則會創建該文件;如果文件存在,則寫入的數據會被加到文件尾后,即文件原先的內容會被保留(EOF?符保留)。 |
| a+ | 以附加方式打開可讀/寫的文件。若文件不存在,則會創建該文件,如果文件存在,則寫入的數據會被加到文件尾后,即文件原先的內容會被保留(EOF符不保留)。 |
| wb | 以只寫方式打開或新建一個二進制文件,只允許寫數據。 |
| wb+ | 以讀/寫方式打開或新建一個二進制文件,允許讀和寫。 |
| wt+ | 以讀/寫方式打開或新建一個文本文件,允許讀和寫。 |
| at+ | 以讀/寫方式打開一個文本文件,允許讀或在文本末追加數據。 |
| ab+ | 以讀/寫方式打開一個二進制文件,允許讀或在文件末追加數據。 |
除了以上的io庫函數還有些常用的
- fseek(),ftell(),rewind()? :更改文件流中的讀/寫字節的位置
- feof(),ferr(),fileno() : 測試文件流狀態
- fdopen()? ?用文件描述符打開文件流
- freopen() 以新名稱重新打開現有的流
- setbuf(),setvbuf()? 設置緩沖方案
- popen()? 創建管道,復刻子進程來調用shell
二、緩沖方案
每個文件流都包含有一個FILE 結構體,其中包含一個內部緩沖區。由于文件是存儲在磁盤中。頻繁的寫磁盤耗時耗資源。通常把內容放在內存中,再把該內存中的數據一次性寫入文件。緩沖方案有三種
1)無緩沖 _IONBUF:每次讀取的字符盡快地傳輸到文件或者從文件中傳出,例如stderr
2)? 行緩沖 _IOLBUF:每次讀取的字符寫入到緩沖區中,讀取到換行符時,再將緩沖區的內容傳輸/傳出到文件,例如 stdout
3) 全緩沖 _IOFBUF:把全部讀取的字符都寫入到緩沖區,再一次性傳輸/傳出到文件。例如文件流 。?
#include <stdio.h>int main(){//setvbuf(stdout,NULL,_IONBUF,0);int i=10;while(i--){printf("hi ");// fflush(stdout);sleep(1);} }上面的案例直到程序執行完都不會看見輸出的信息。因為stdout是行緩沖的,而循環體中都沒遇見換行符。如果打開 setvbuf 注釋,把stdout設置為無緩沖,那么輸出的信息是每個字符每個字符地出現。如果打開 fflush 注釋,把stdout的緩沖區清除,那么緩沖區內的信息再清除時都會被輸出出來
三、變參函數
? ? ?在C程序中printf 函數十分獨特,應為它可以接收任意數量的參數(從第二個參數開始,每個參數用來代替第一個參數中的占位符)。在其函數內部,可以在stdarg中通過宏訪問參數.
- ? ?void va_start(va_list ap , last);? ? ? //從last參數開始創建參數列表
- ? type va_arg(va_list ap , type)? ? ? ?// 指明下一個參數的數據類型,并提取出來,同時ap指向下一個元素
- ?va_end(va_list ap)? ? ? // 將 ap 重置為NULL
? ? ?變參函數原理根據不同編譯器有不同的算法。例如在32位GCC中以下myprintf(char *,...)算法依舊有效。
int myprintf(char *fmt , ...){char * cp = fmt;int *ip = (int *)&fmt +1; }根本原理是因為一個函數的形參在內存棧中是挨在一起的。
變參函數的用法示例如下:
#include <stdio.h> #include <stdarg>//輸出形參列表中 m 個int類型和n個字符串的信息 int func (int m ,int n,...){va_list ap;va_start(ap,n); //獲取形參 n 之后的參數列表apfor (int i =0 ; i<m ;i++){printf ("%d ",va_arg(ap,int));}for (int i =0 ; i<n ;i++){printf ("%s ",va_arg(ap,char*));}va_end(ap);}int main (){func(3,2 ,1,2,3,"test","ok"); }總結
以上是生活随笔為你收集整理的Linux C: IO库函数,文件流缓冲,变参函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux C: 文件操作相关的系统调用
- 下一篇: Linux C : TCP/IP 和 网