• 《APUE》-第五章标准IO库


         大多数UNIX应用程序都使用I/O库,本章说明了该库所包含的所有函数,以及某些实现细节和效率方面的考虑。同时需要重点关注标准I/O使用了缓冲的技术,但同时也是因为它的出现,产生了很多细节上的问题.

    流和FILE对象

        unix系统调用的函数都是针对文件描述符操作的.而标准I/O库,它们的操作则是围绕流进行的。当用标准I/O库打开或创建一个文件时,使一个流与一个文件相关联.

       关于流定向的问题,当一个流刚被创建时,它并没有定向,我们可以在未定向的流上使用一个多字节I/O函数或者单字节的函数.

    #include <stdio.h>
    #include <wchar.h>
    
    int fwide(FILE* fp,int mode); 

       当我们打开一个流时,标准I/O函数fopen返回的是一个指向FILE对象的指针.该对象是一个结构,它包含了:用于实际I/O的文件描述符、指向用于该流缓冲区的指针、缓冲区的长度、当前在缓冲区的字符数以及出错标志等。

      

    缓冲

    标准I/O库提供缓冲的目的是为了尽可能减少使用read和write调用的次数,它也对每个I/O流自动地进行缓冲管理,从而避免了应用程序需要考虑带来的麻烦.标准I/O提供了三种缓冲:

    • 全缓冲:在填满标准I/O缓冲区后才进行实际I/O操作.对于驻留在磁盘上的文件通常是全缓冲的.
    • 行缓冲:当在输入和输出中遇到换行符时,标准I/O库执行I/O操作.这允许我们一次输出一个字符,但只有在写额一行之后才进行实际I/O操作。当流涉及一个终端时(如标准输入和标准输出),通常使用行缓冲.
    • 不带缓冲:标准I/O库不对字符进行缓冲存储。通常标准出错流stderr是不带缓冲的.这就使得出错信息可以尽快显示出来.

    对于任何一个给定的流,我们可以自己设定缓冲类型

    void setbuf(FILE* fp,char* buf);
    int  setvbuf(FILE* fp,char* buf,int mode,size_t size);
    //返回值:若成功则返回0,若出错则返回非0值

    具体参数:setbuf函数

    关闭缓冲:buf=NULL

    setvbuf 具体参数:mode参数:_IOFBF 全缓冲  _IOLBF 行缓冲 _IONBF 不带缓冲

    如果指定全缓冲或行缓冲,则buf和size可选择地指定一个缓冲区及其长度.

    打开与关闭流:

    #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);//获取一个现有的文件描述符,并使一个标准的IO流与该描述符相结合.
    int fclose(FILE* fp);//关闭文件流

    读写流:

    一次一个字符的I/O.

    #include <stdio.h>
    int getc(FILE* fp);
    int fgetc(FILE* fp);
    int getchar(void);
    //若成功则返回下一个字符,若已到达文件尾或出错则返回EOF
    
    /*******对应的输出函数***********/
    int putc(int c,FILE* fp);
    int fputc(int c,FILE* fp);
    int putchar(int c);

    一次一行字符的I/O

    #include <stdio.h>
    
    char* fgets(char* buf,int n,FILE* fp);
    char* gets(char* buf);
    //成功则返回buf,若已到达文件尾或者出错则返回NULL
    
    int fputs(const char* str,FILE* fp);
    int puts(const char* str);
    //若成功则返回非负值,若出错则返回EOF

    注意点:

    对于fgets,必须指定缓冲区的长度n,此函数一直读到下一个换行符为止,但是不超过n-1个字符,读入的字符被送入缓冲区.该缓冲区以null结尾。而gets是一个不安全的函数,它可能会造成缓冲区溢出.同时它与fgets的另一个区别是gets并不将换行符存入缓冲区中.

    二进制I/O

    #include <stdio.h>
    size_t fread(void* ptr,size_t size,size_t obj,FILE* fp);
    size_t fwrite(const void* ptr,size_t size,size_t obj,FILE* fp);
    //读或写的对象数

    通常用于读或写一个二进制数组或者用于读写一个结构体.

    格式化I/O:

    #include <stdio.h>
    
    int printf(const char* format,...);
    int fprintf(FILE* fp,const char* format,...);//若成功则返回输出的字节数,若输出出错则返回负值.
    int sprintf(char* buf,const char* format,...);
    int snprintf(char* buf,size_t n,const char* format,...);
    //若成功则返回存入数组的字符数,若编码出错则返回负值.
    
    
    int scanf(const char* format,....);
    int fscanf(FILE* fp,const char* format,...);
    int sscanf(const char* buf,cpnst char* format,...);
    //指定的输入项数;若输入出错或在任意变换前已到达文件尾则返回EOF.

    定位流:

    #include <stdio.h>
    
    long ftell(FILE* fp);//若成功则返回当前文件位置指示,若出错则返回-1L.
    int fseek(FILE* fp,long offset,int whence);//若成功则返回0,,若出错则返回非0值
    
    void rewind(FILE* fp);
     

    临时文件:

    #include <stdio.h>
    
    char* tmpnam(char* ptr);//指向唯一路径名的指针
    FILE* tmpfile(void);//若成功则返回文件指针,若出错则返回NULL.

    char* tempnam(const char* directory,const char* prefix);//返回指向唯一路径名的指针.

    示例:

    #include <stdio.h>
    
    char* tmpnam(char* ptr);//指向唯一路径名的指针
    FILE* tmpfile(void);//若成功则返回文件指针,若出错则返回NULL.
    
    
    #include <stdio.h>
    
    int main(void){
        char name[L_tmpnam],line[MAX_LINE];
        FILE *fp;
        
        printf("%s
    ",tmpnam(NULL));//first tmp name
        
        tmpnam(name);
        printf("%s
    ",name);
        
        if((fp=tmpfile())==NULL){
             printf("tmpfile error");
             exit(-1);
        }
        
        fputs("one line of output
    ",fp);
        rewind(fp);
        
        if(fgets(line,MAX_LINE,fp)==NULL){
            printf("fgets error
    ");
            exit(-1);
        }
        
        fputs(line,stdout);
        exit(0);
    }
  • 相关阅读:
    PostgreSQL Replication之第四章 设置异步复制(4)
    PostgreSQL Replication之第四章 设置异步复制(3)
    PostgreSQL Replication之第四章 设置异步复制(2)
    PostgreSQL Replication之第四章 设置异步复制(1)
    PostgreSQL Replication之第三章 理解即时恢复(4)
    Hdu3065 病毒侵袭持续中
    poj3974 Palindrome
    poj1204 Word Puzzles
    Hdu2222 Keywords Search
    Codeforce 633.C Spy Syndrome 2
  • 原文地址:https://www.cnblogs.com/sixue/p/4034524.html
Copyright © 2020-2023  润新知