標準I/O庫

來源:互聯網
上載者:User

標籤:unix   linux   檔案io   緩衝   輸入輸出   

標準的I/O是由ANSI C標準規定的,不僅可以在UNIX/Linux上使用,還可以在其他地方使用。
標準I/O庫對應檔案的操作是圍繞流(stream)進行的。當用標準I/O庫開啟或建立檔案時,便使一個流與一個檔案相關聯。標準I/O庫的函數對於檔案的描述是基於FILE對象指標的,該對象是一個結構體,包含了I/O庫管理流所需要的全部資訊:用於實際I/O的檔案描述符、指向流緩衝的指標、緩衝長度、當前在緩衝中的字元數、出錯標誌等等。

標準輸入、標準輸出、標準出錯
和檔案描述符STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO類似,標準I/O也有這三項,它們是通過預定義的指標stdin、stdout、stderr來引用的。這三個指標定義於標頭檔<stdio.h>。

緩衝
眾所周知,I/O操作使比較耗時的。如果每次I/O操作只進行少量讀或寫,那麼I/O操作的次數肯定會很多。緩衝的作用就是把進行I/O操作的資料先存起來,等到存到一定量時再進行實際的I/O操作。系統調用read和write是不帶緩衝的,所以每次調用都會進行I/O操作。標準I/O是帶緩衝的,它會對流自動進行緩衝管理。標準I/O提供以下三種緩衝:
1、全緩衝:指的是在填滿I/O緩衝區後才進行實際的I/O操作。對於磁碟上的檔案通常是由標準I/O實施全緩衝的。在一個流上第一次執行I/O操作時,相關標準I/O函數通常調用malloc開闢使用的緩衝區。
2、行緩衝:指的時在輸入或輸出遇到分行符號時,標準I/O庫執行實際的I/O操作。當流涉及到終端時(如標準輸入、標準輸出),通常使用行緩衝。
3、不帶緩衝:指的是標準I/O庫不對字元進行緩衝儲存,直接調用系統調用。標準出錯stderr通常是不帶緩衝的,這樣就可以使得錯誤資訊儘快顯示出來。
這裡還要提到一個概念:沖洗(flush),指的是清空緩衝區,緩衝區資料進行I/O操作。調用函數fflush就可以沖洗一個流。
可以通過函數更改緩衝類型:
#include<stdio.h>
void setbuf( FILE *restrict fp, char *restrict buf);
int setvbuf( FILE *restrict fp, char *restrict buf, int mod, size_t size);
沖洗流使用:
#include<stdio.h>
int fflush(FILE *fp);
如果fp為NULL,則所有輸出資料流被沖洗。

開啟流
#include<stdio.h>
FILE *fopen(const char *restrict pathname, const char *restrict type);
FILE *fopen(const cahr *restrict pathname, const char *restrict type, FILE *restrict fp);
FILE *fdopen(int filedes, const char *type);
關閉流
#include<stdio.h>
int fclose(FILE *fp);


讀寫流
流開啟之後,可以在三種不同類型的非格式化I/O(還有格式化的I/O)中進行選擇,對其進行讀寫操作:
1、每次一個字元的I/O。每次讀或寫一個字元,如果流是帶緩衝的,則標準I/O會處理所有緩衝。
2、每次一行的I/O。如果想要一次讀或寫一行,使用fgets或fputs,每次都以一個分行符號終止。
3、直接I/O。fread和fwrite支援這種類型的I/O。每次I/O操作讀或寫某種數量的對象,而這個對象具有指定的長度。這兩個函數常用於從二進位的檔案中每次讀或寫一個結構。


每次讀入一個字元的I/O(函數結尾c說明每次一個字元,char)
#include<stdio.h>
int getc(FILE* fp);
int fgetc(FILE *fp);
int getchar(void);//等價於getc(stdin)
對應於上面,每個輸入函數都有一個輸出函數
#include<stdio.h>
int putc(int c, FILE *fp);
int fputc(int c, FILE *fp);
int putchar(int c);//等價於putchar(c,stdout);


每次一行I/O(函數結尾s說明每次一行,string)
#include<stdio.h>
char *fgets(char *restrict buf, int n, FILE *restrict fp);
char *gets(char *buf);//從標準輸入讀
對應於上面,每個輸入函數都有一個輸出函數
#include<stdio.h>
int fputs(const char *restrict str, FILE *restrict fp);
int puts(const char *str);


二進位I/O
使用二進位I/O常常一次操作一個結構。如果使用getc或puts讀寫一個結構,那麼必須迴圈通過整個結構,每次迴圈處理一個位元組,非常耗時。如果使用fputs或fgets,那麼fputs/fgets遇到null位元組就停止,而結構中可能含有NULL位元組,不能實現讀結構的要求。因此提供了兩個函數執行二進位的I/O.
#include<stdio.h>
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);
二進位I/O的基本問題是:只能用於在同一檔案系統上操作。隨著網路檔案系統系統的興起,這兩個函數的使用就受到限制。


格式化I/O
格式化輸入的4個函數
#include<stdio.h>
int printf(const char *restrict format,……);
int fprintf(FILE *restrict fp, const char *restrict format,……);
int sprintf(char *restrict buf, const char* restrict format, ……);
int sprintf(char *restrict buf, size_t n, const char *restrict format,……);
格式化輸入
#include<stdio.h>
int scanf(const char *restrict format,……);
int fscanf(FILE *restrict fp, const char *restrict format,……);
int sscanf(const char *restrict buf, const char *restrict format,……);


在UNIX系統中,標準I/O庫最終都要調用檔案I/O的系統調用的。每個標準I/O流都有一個與其相關聯的檔案描述符,可以用下面函數來獲得對應的檔案描述符
#incude<stdio.h>

int fileno(FILE *fp);

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.