• UNIX环境高级编程 标准IO库


    标准I/O库处理很多细节,使得便于用户使用。

    流和 FILE 对象

    对于标准I/O库,操作是围绕 流(stream)进行的。当用标准I/O打开或创建一个文件时,我们已使一个流与一个文件相关联。

    对于ASCII字符集,一个字符用一个字节表示。对于国际字符集,一个字符可用多个字节表示。流的定向决定所读,写的字符是单字节还是多字节。

    一个流在创建的最初,并没有定向,如果对未定向的流使用多字节I/O函数,则将该流定向为款定向的,反之如果使用单字节I/O函数,则将流的定向设为字节定向的。

    改变流的定向的函数(只有两个):

    freopen : 清楚一个流的定向

    fwide        :   设置流的定向

    int fwide ( FILE *fp , int mode );

    宽定向返回正值,字节定向返回负值,未定向的返回0;

    • 如果mode参数为负 , fwide试图使指定的流是字节定向
    • 如果mode参数为正 , fwide试图使指定的流是宽定向的
    • 如果mode参数为 0  , fwide将不试图设置流的定向,但返回标识该流定向的值。

    fwide 并不改变已定向流的定向。

    标准输入 , 标准输出 , 标准错误。

    文件描述符 分别为 STDIN_FILENO , STDOUT_FILENO , STDERR_FILENO

    通过预定文件指针 stdin , stdout , stderr。这三个文件指针分别在头文件<stdio.h>中

    缓冲

    标准I/O 库提供缓冲的目的是尽可能减少使用 read 和 write 调用的次数。

    标准I/O 提供了一下 3种类型的缓冲:

    全缓冲:在填满标准I/O缓冲区后才进行实际I/O操作。

    行缓冲:在输入和输出遇到换行符时,标准I/O库执行I/O操作。

    不缓冲:比如strerr,这样使得出错信息可以尽快显示出来。

    对任何一个给定的流,可以调用下列两个函数中的一个更改缓冲类型。

    void setbuf ( FILE *restrict fp , char *restrict buf ) ;

    int setvbuf ( FILE *restrict fp , char *restrict buf , int mode , size_t size );

    使用 setbuf 函数打开或关闭缓冲机制。为了带缓冲进行I/O,参数buf指向一个长度为BUFSIZE的缓冲区,为了关闭缓冲,将buf设置为NULL。

    使用 setvbuf , 可以精确的说明所需缓冲类型。 mode 参数:

    _IOFBF     全缓冲

    _IOLBF     行缓冲

    _IONBF    不缓冲

    147页有图。

    打开流

    下列三个函数打开一个标准I/O流。

    FILE *fopen ( const char *restrict pathname , const char *restrict type );

    FILE *freopen ( const char *restrict pathname , const char *restrict type , FILE *restrict fp );

    FILE *fdopen ( int fd , const char *type );

     

    区别在于:

    1. fopen打开一个路径名为pathname的一个指定文件
    2. freopen在一个指定的流上打开一个指定的文件 。
    3. fdopen取一个文件描述符,并使一个标准的I/O流与该描述符结合。

    type有15种不同的值 —— 图5.2

     

     

    读和写流

    输入函数:

    以下三个函数可以一次读一个字符

    int getc ( FILE *fp )

    int fgetc (FILE *fp )

    int getchar ( void )

     

    getchar 等同于 getc(stdin)。

    getc可被实现为宏,fgetc不能实现为宏。

    1. getc的参数不应当是具有副作用的表达式
    2. fgetc一定是一个函数,所以可以得到其地址。
    3. 调用fgetc的时间可能比getc的时间长。

     

    由于不管出错还是达到文件尾端。三个函数都是返回同样的值。为了区分,调用ferror 或 feof

    int ferror ( FILE *fp )

    int feof ( FILE *fp )

    在大多数实现中,为每个流在FILE对象中维护了两个标志:

    出错标志

    文件结束标志

    输出函数:

    int putc ( int c , FILE *fp )

    int fputc ( int c , FILE *fp )

    int putchar ( int c )

     

    putchar( C ) 等同于 putc ( c , stdout ) ,  putc 可被实现为宏 , 而fputc不能实现为宏。

    每次一行 I/O

    char *fgets ( char *restrict buf , int n , FILE *restrict fp )

    char *gets ( char *buf )

    gets从标准输入读, fgets 从指定的流读。

    对于 fgets , 必须指定缓冲的长度为 n 。 此函数一直读到下一个换行符为止。

    gets是一个不推荐使用的函数,因为不能指定在使用gets时缓冲区的长度。可能造成缓冲区溢出。

    gets并不将换行符存入缓冲区

    fputs 和 puts 提供每次输出一行的功能

    int fputs ( const char *restrict str , FILE *restrict fp )

    int puts ( const char *str )

    函数 fputs 将一个以 null 字节终止的字符串写到指定的流,尾端的null不写出。

    函数 puts 将一个以 null 字节终止的字符串写到标准输出,终止符不写出。但随后将一个换行符写到标准输出。

    应当尽量使用 fgtes 和 fputs。

    标准 I/O 的效率

    二进制 I/O

    以下两个函数用于执行二进制 I/O 操作

    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 );

     

     

     

  • 相关阅读:
    USACO Section 1.3 : Mixing Milk
    USACO Section 1.3 : Prime Cryptarithm
    USACO Section 1.2 : Name That Number
    USACO Section 1.3 : Calf Flac
    USACO Section 1.2 : Palindromic Squares
    Global.asax详解
    sql语句字符串处理大全
    ASP.net:URL重写实现IHttpHandler接口
    asp.net中使用基于角色role的Forms验证
    时间Table.TransformColumns(Power Query 之 M 语言)
  • 原文地址:https://www.cnblogs.com/wchyi/p/5544383.html
Copyright © 2020-2023  润新知