[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 
void setbuf(FILE* fp, char* buf)
int setvbuf(FILE* fp, char* buf, int mode,size_t size); int fflush(FILE* fp) //强制刷新流


4. 打开流

#include 
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(FILE* fp);
type 为:
r,rb,w,wb,a,ab,r+,r+b,rb+,w,w+b,w。 w把文件截断为0, a定位文件到末尾。b 为二进制文件读写。


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

#include 
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 
int getc(FILE * f p) ;
int fgetc(FILE * f p) ;
int getchar(void);
成功则为下一个字符,若已处文件尾端或出错则为EOF. getc 为宏,fgetc为函数

使用 ferror 或者feof 查看读结束状态,clearerr 清除error. ugetc可以送回读出来的字符。

7.字符写

字符写跟字符读正好相反。

#include 
int putc(int c, FILE * fp) ;
int fputc(int c, FILE * fp);
int putchar(int c) ;

8. 行读写

#include 
char *fgets(char * buf, int n,FILE * fp) ;
char *gets(char * buf) ; //基本不建议用,防止buf溢出。

#include 
int fputs(const char * str, FILE * fp) ;
int puts(const char * str);


9. 二进制读写

#include 
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 
#include 
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 
long ftell(FILE * fp) ;
返回:若成功则为当前文件位置指示,若出错则为- 1 L
int fseek(FILE * fp,long offset,int whence) ;
返回:若成功则为0,若出错则为非0
void rewind(FILE * fp) ; //使文件重新回到头

#include 
int fgetpos(FILE * fp, fpos_t * pos) ;
int fsetpos(FILE * fp, const fpos_t * pos) ;

11. 格式化IO

经典的几个格式化输出函数

#include 
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 
#include 
#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);
}
~






你可能感兴趣的:([APUE]再读之 标准IO库)