本文章說明標準I/O庫
1.流和FILE對象
對於文件IO都是針對於文件描述符的,但是對於標準I/O,則是針對於流進行的
當用標準I/O庫打開一個文件的時候,我們已使一個流和一個文件相關聯
對於ASCII字符集,一個字符用一個字節表示,對於國際字符,一個字符可用多個字節表示
標準I/O文件流可用於單字節或多字節字符集
流的定向決定了所讀、寫的文件是單字節還是多字節的,當一個流被創建的時候,它沒有被定向
如果在沒有定向的流中使用多字節的I/O函數,則將該流的定向設置爲寬定向的
如果在沒有定向的流中使用單字節的I/O函數,則將該流的定向設置爲字節定向
fwide函數可以設置流的定向
#include <stdio.h>
#include <fchar.h>
int fwide(FILE *fp, int mode);
//若流是寬定向的返回正值,若流是字節定向的返回負值,若流是未定向的返回0
若mode是正值,則函數試圖設置流爲寬定向的
若mode是負值,則函數試圖設置流爲字節定向的
若mode是0,則函數不設置流的定向,但是將返回標識該流定向的值
注意fwide函數不設置已經定向的流
2.標準輸入,標準輸出和標準錯誤輸出
在<stdio.h>中定義了這三個流stdin, stdout, stderr
這三個流可以自動地被進程使用
3.緩衝
標準I/O提供緩衝是爲了儘量減少read和write函數的調用
標準I/O提供了三種類型的I/O
(1)全緩衝
當緩衝區全部寫滿的時候在進行寫入操作。
(2)行緩衝
當遇到換行符的時候進行寫入操作,或者遇到換行符之前,緩衝區填滿也進行寫入
(3)不緩衝
ISO C要求下列緩衝特性:
當且僅當標準輸入輸出不涉及交互式設備的時候,它們纔是全緩衝的
標準出錯決不是全緩衝的
很多系統默認下列類型的緩衝特性:
標準出錯不帶緩衝
如若是涉及終端設備的其他流的時候,則它們是行緩衝的,否則是全緩衝的
可以調用下面兩個函數更改緩衝類型:
#include <stdio.h>
void setbuf(FILE *restrict fp, char *restrict buf);
int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);
//成功返回0,出錯返回非零值
setbuf函數中,若buf非空,buf長度爲BUFSIZ,則緩衝類型是全緩衝或者行緩衝,當buf爲NULL的時候不緩衝
setvbuf函數中,不同的mode有不同的處理方式
_IOFBF 全緩衝,buf如下
當buf非空,緩衝區爲長度爲size的用戶buf
當buf爲BULL的時候,緩衝區爲合適長度的系統緩衝區
_IOLBF 行緩衝,buf同理
_IONBF 不緩衝,buf和size忽略
強制沖洗一個流,將未寫入的數據都傳送給內核
#include <stdio.h>
int ffush(FILE *fp);
//成功返回0,出錯返回EOF
4.打開流
打開一個標準I/O流
#include <stdio.h>
FILE *fopen(const char *restrict pathname, const char *restrict type);
//打開一個指定的文件
FILE *freopen(const char *restrict pathname, const char *restrict type, FILR *restrict fp);
//在一個指定的流上打開一個指定的文件,如若該流已經打開,則先關閉該流,若該流已經定向,則清除
FILE *fdopen(int filedesm const char *type);
//將一個現有的文件描述符與一個標準I/O流結合起來
//以上函數若成功返回文件指針,失敗返回NULL
type指定對該I/O流的讀寫方式
r或rb 爲讀而打開
w或wb 把文件截短至0長,或爲寫而創建
a或ab 追加,或爲寫而創建
r+或r+b或rb+ 爲讀和寫而打開
w+或w+b或wb+ 把文件截短至0長,或爲讀寫而打開
a+或a+b或ab+ 在文件尾讀和寫而打開或創建
b作爲type的一部分爲了區分文本文件和二進制文件,但是UNIX系統並不區分這兩種類型的文件,在UNIX下b是無用的
fdopen在爲寫而打開的時候並不截短文件
當以讀和寫類型打開一個文件的時候,有以下限制:
如果中間沒有fflush、fseek、fsetpos和rewind的時候,則在輸出後面不能直接跟隨輸入
如果中間沒有fseek、fsetpos或rewind,或者一個輸入操作沒有達到文件尾端,在輸入操作之後不能跟隨輸出
調用fclose關閉一個打開的流
#include <stdio.h>
int fclose(FILE *fp);
//成功返回0,出錯返回EOF
5.讀和寫流
以下三個函數用於一次讀一個字符
#include <stdio.h>
int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void);//等價與getc(stdin);
//成功返回下一個字符,達到文件尾或出錯返回EOF
爲了區分是否達到文件尾還是出錯,有以下函數
#include <stdio.h>
int ferror(FILE *fp);
int feof(FILE *fp);
//若條件爲真,返回非零值,否則返回0
void clearerr(FILE *fp);//清除這兩個標誌
可以調用下面的函數將已經讀出來的字符壓送會流中
#include <stdio.h>
int ungetc(int c, FILE *fp);
//成功返回c,失敗返回EOF
使用這個函數時,字符送到了流的緩衝區中
輸出函數
#include <stdio.h>
int putc(int c, FILE *fp);
int fputc(int c, FILE *fp);
int putchar(int c);
//成功返回buf,出錯返回EOF
6.每次一行I/O
下面函數提供每次輸入一行的函數
#include <stdio.h>
char *fgets(char *restrict buf, int n, FILE *restrict fp);
char *gets(char *buf);
//成功返回buf,到達文件尾或失敗返回EOF
//gets函數不安全,不建議使用
每次輸出一行:
#include <stdio.h>
int fputs(const char *restrict str, FILE *restrict fp);
int puts(const char *str);
//成功返回非負值,出錯返回EOF
7.二進制I/O
執行二進制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);
//返回讀和寫的對象數
//nobj爲讀寫的對象數
8.格式化I/O
格式化輸出函數
#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 snprintf(char *restrict buf, size_t n, const char *restrict format, ...);
//成功返回存入數組的字符數,失敗返回負值
printf格式化寫到標準輸出
fprintf格式化寫到指定的流
sprintf和snprintf格式化寫到數組buf中
格式化輸入函數
#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, ...);
//成功返回指定的輸入項數,出錯或者達到了文件結尾返回EOF
9.實現細節
獲取一個流所對應的文件描述符
#include <stdio.h>
int fileno(FILE *fp);
//返回與流相關的文件描述符
10.臨時文件
創建臨時文件
#include <stdio.h>
char tmpnam(char *ptr);
//返回唯一路徑名的指針
FILE *tmpfile(void);
//成功返回文件指針,失敗返回NULL
每次調用tmpnam返回一個與文件名不同的有效路徑名字符串
tmpfile產生一個臨時的二進制文件(wb+)。在關閉該文件或程序結束的時候將自動刪除這個文件。
【APUE】標準I/O庫
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章
udp服務器端demo
zyw067
2018-08-26 20:47:13
【Linux】存儲映射I/O—mmap
萧-十一
2018-08-26 17:04:39
sem_init
carpediem523
2018-08-26 15:47:15
APUE讀書筆記-第十四章-高級I/O
qiao_yi_fan
2018-08-26 14:22:33
APUE讀書筆記-第十五章-進程間通信
qiao_yi_fan
2018-08-26 14:22:33
TCP IP詳解卷2之mbuf宏與函數
shinichr
2018-08-26 11:14:24
socket阻塞與非阻塞模式區別
shinichr
2018-08-26 11:14:24
TCP-IP詳解 卷2:實現之mbuf存儲器緩存
shinichr
2018-08-26 11:14:18
APUE-文件與目錄:一個LINUX用戶登陸函數
向太阳
2018-08-25 20:00:40
APUE:線程:線程池的實現
向太阳
2018-08-25 20:00:40
APUE-線程:pthread_create的實現與apue2的區別
向太阳
2018-08-25 20:00:40
APUE-文件與目錄:dup與dup2
向太阳
2018-08-25 20:00:40
APUE:進程:wait、waitpid
向太阳
2018-08-25 20:00:40
APUE:線程:讀寫鎖rwlock
向太阳
2018-08-25 20:00:40