[APUE]再讀之 標準IO庫

本章介紹標準IO庫


1. FILE對象

標準IO庫一切函數基於FILE對象。FILE對象包含了管理該流的所有信息: 文件描述符,指向流緩存的指針,緩存的長度,緩存的字節數以及出錯標識等


2. 標準輸入,標準輸出和標準出錯。

對應非標準IO: STDIN_FILENO, STDOUT_FILENO,STDERR_FILENO

對於標準IO: stdin,stdout,stderr.


3. 緩存

爲了儘可能減少使用read和write調用的數量,標準IO提供緩存。全緩存,行緩存和不緩存。

當且僅當不涉及交互設備的時候,他們纔是全緩存的。標準出錯不會是全緩存。

#include <stdio.h>
void setbuf(FILE* fp, char* buf)
int setvbuf(FILE* fp, char* buf, int mode,size_t size); int fflush(FILE* fp) //強制刷新流


4. 打開流

#include <stdio.h>
FILE *fopen(const char* pathname,const char* type);
FILE *freopen(const char* pathname,const char* type,FILE* fp);
FILE *fdopen(int filedes,const char* type)
int fclose(<span style="font-family: Arial, Helvetica, sans-serif;">FILE* fp</span>);
type 爲:
r,rb,w,wb,a,ab,r+,r+b,rb+,w,w+b,w。 w把文件截斷爲0, a定位文件到末尾。b 爲二進制文件讀寫。


freopen 的妙用:用文件冒充stdin,stdout

#include <stdio.h>
int main()
{
int a,b;
freopen("/tmp/in.txt","r",stdin);
freopen("/tmp/out.txt","w",stdout);
while(scanf("%d %d",&a,&b)!=EOF)
    printf("%d\n",a+b);
fclose(stdin);
fclose(stdout);
return 0;
}

5.讀和寫流的方式

每次處理一個字符;每次處理一行;直接IO。

6.字符讀

#include <stdio.h>
int getc(FILE * f p) ;
int fgetc(FILE * f p) ;
int getchar(void);
成功則爲下一個字符,若已處文件尾端或出錯則爲EOF. getc 爲宏,fgetc爲函數

使用 ferror 或者feof 查看讀結束狀態,clearerr 清除error. ugetc可以送回讀出來的字符。

7.字符寫

字符寫跟字符讀正好相反。

#include <stdio.h>
int putc(int c, FILE * fp) ;
int fputc(int c, FILE * fp);
int putchar(int c) ;

8. 行讀寫

#include <stdio.h>
char *fgets(char * buf, int n,FILE * fp) ;
char *gets(char * buf) ; //基本不建議用,防止buf溢出。

#include <stdio.h>
int fputs(const char * str, FILE * fp) ;
int puts(const char * str);


9. 二進制讀寫

#include <stdio.h>
size_t fread(void * ptr, size_t size, size_t nobj, FILE * fp) ;
size_t fwrite(const void* ptr, size_t size, size_t nobj,FILE* fp); //缺點是異構系統上二進制讀寫會產生問題。

二進制讀寫的一個簡單demo:

#include <stdio.h>
#include <string.h>
struct school
{
    int number;
    char name[1024];
};

int main()
{
    struct school southeast;
    southeast.number = 4096;
    memset(southeast.name, 1024,0);
    strcpy(southeast.name, "southeast university");
    FILE* fp = fopen("/tmp/bintest","w");
    if(fwrite(&southeast, sizeof(struct school),1, fp)!=1)
    {
        printf("fwrite error\n");
        return -1;
    }
    fclose(fp);
    FILE* fp2 = fopen("/tmp/bintest","r");
    struct school su;
    if(fread(&su, sizeof(struct school),1, fp2)!=1)
    {
        printf("fread error error\n");
        return -1;
    }
    printf("number =%d,name=%s\n",su.number, su.name);
}

10. 定位文件

#include <stdio.h>
long ftell(FILE * fp) ;
返回:若成功則爲當前文件位置指示,若出錯則爲- 1 L
int fseek(FILE * fp,long offset,int whence) ;
返回:若成功則爲0,若出錯則爲非0
void rewind(FILE * fp) ; //使文件重新回到頭

#include <stdio.h>
int fgetpos(FILE * fp, fpos_t * pos) ;
int fsetpos(FILE * fp, const fpos_t * pos) ;

11. 格式化IO

經典的幾個格式化輸出函數

#include <stdio.h>
int printf(const char *format, ...);
int fprintf(FILE * fp, const char *format, ...);
int sprintf(char * buf, const char *format, ...);

int scanf(const char * format, ...);
int fscanf(FILE * fp, const char *format, ...);
int sscanf(const char * buf, const char *format, ...);


12. 臨時文件

簡單demo:

#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 1024


int main(int argc, char* argv[])
{
    char name[L_tmpnam] , line[MAXLINE];
    printf("tmp name is %s\n", tmpnam(NULL));
    tmpnam(name);
    printf("tmp name is %s\n", (name));
    FILE* fp;
    if((fp=tmpfile())==NULL)
    {
        printf("error");
        exit(0);
    }
    fputs("put one line to file\n",fp);
    rewind(fp);
    if (fgets(line,sizeof(line),fp)==NULL)
    {
        printf("fgets error");
        exit(0);
    }
    fputs(line,stdout);
    exit(0);
}
~






發佈了45 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章