標準I/O(C庫函數)

與操作系統獨立,只能操作常規文件,有緩衝區
常規文件:ASCII碼文件(文本文件)、二進制文件

緩衝區:減少用戶和內核切換的次數,減小系統開銷。當對文件進行操作時,緩衝區纔會被開闢。當進程結束時自動調用fclose(),關閉已打開的文件,刷新緩衝區。

全緩衝:4k字節,用於標準文件操作,當緩衝區滿的時候給內核。

行緩衝:1k字節,用於標準輸入輸出,當緩衝區遇到‘\n’時給內核。

不帶緩衝:0字節,用於標準出錯,數據不經過緩衝區,直接給內核。

內核中有高速緩存,定時刷新至硬盤。


描述     文件描述符int    文件描述符對應的宏   文件指針FILE*
標準輸入        0            STDIN_FILENO         stdin
標準輸出        1            STDOUT_FILENO        stdout
標準錯誤        2            STDERR_FILENO        stderr


int fflush(FILE *fp); 用於將緩衝區中的數據實時刷新至內核。

FILE *fopen(const char *path,const char *mode);
FILE *fdopen(int fd,const char *mode);   //聯繫流與文件描述符
FILE *freopen(const char *path,const char *mode,FILE *stream);  //用於重定向
int fclose(FILE *stream);
當一個進城正常終止時(直接調用exit函數,或從main函數返回),系統會自動調用fclose()函數,刷新所有緩衝區,所有打開的標準I/O流都被關閉。
爲了編程規範,使用文件後,一定要顯式的調用fclose()。 


mode參數:
r或rb      打開只讀文件,該文件必須存在。
r+或rb+    打開可讀寫的文件,該文件必須存在。
w或wb      打開只寫文件,若文件存在則清空。若文件不存在則創建該文件。
w+或wb+    打開可讀寫文件,若文件存在則清空,若文件不存在則創建該文件。
a或ab      以附加方式打開只寫文件,若不存在則創建,若文件存在,寫入的數據追加到文件尾,即原先內容被保留。
a或ab+     以附加方式打開可讀寫文件,若不存在則創建,若文件存在,寫入的數據追加到文件尾,即原先內容被保留。
b 表示以二進制方式打開文件。

二進制和文本模式的區別

1.在windows系統中,文本模式下,文件以"\r\n"代表換行。若以文本模式打開文件,並用fputs等函數寫入換行符"\n"時,函數會自動在"\n"前面加上"\r"。即實際寫入文件的是"\r\n" 。

2.在類Unix/Linux系統中文本模式下,文件以"\n"代表換行。所以Linux系統中在文本模式和二進制模式下並無區別。


每次一個字符的I/O:如果流是帶緩衝的,標準I/O函數處理所有緩衝。
int fgetc(FILE *stream);  文件結尾或出錯都返回EOF
while(!feof(fp)&&!ferror(fp))
{

    ch = fgetc(fp);
    if(ch == EOF) break;
    printf("%c",ch);
}
int fputc(int c,FILE *stream);

int getc(FILE *stream);

int putc(FILE *stream);

實現爲宏,從流中讀或寫。

int getchar(void); 從終端讀 stdin

int putchar(int c); 輸出到終端 stdout

實現爲宏

檢查文件出錯函數

int feof(FILE *stream);

int ferror(FILE *stream);

int clearerr(FILE *stream);


每次一行的I/O:每行都以‘\n'結束
char *fgets(char *s,int size,FILE *stream);已處文件尾端或出錯返回NULL。
fgets一次只能從文件讀取一行(一行最大1024個字節),在文本文件中,每行最後都是‘\n’,fgets會自動讀取最後的換行符,所以打印時不需加‘\n'。
當用fgets讀取n個字節的數據時,只會返回n-1個字符,最後一個放‘\0’。
while(fgets(str,100,fp1) != NULL)
{
    fputs(str,fp2);
}
int fputs(const char *s,FILE *stream);

char *gets(char *s);int puts(const char *s);


直接I/O:用於讀寫塊或結構體
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
從流stream中讀取size*nmemb個字節到ptr開始的地址空間。
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);


定位流:
int fseek(FILE *stream, long offset, int whence); 用於設定流的文件位置。offset爲正向後偏移,爲負向開頭偏移。whence參數爲 SEEK_SET(開頭)/SEEK_CUR(當前)/SEEK_END(結束)。
long ftell(FILE *stream); 獲取當前的文件位置。
void rewind(FILE *stream); 用於設定流的文件位置爲文件開始。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章