UNIX环境高级编程-第5章- 标准 I/O 库

来源:互联网 发布:淘宝代购关注的人多 编辑:程序博客网 时间:2024/06/06 07:46

5.2 流和 FILE 对象 

前面介绍的文件 I/O 都是针对文件描述符进行操作的,并且是非缓冲区方式的。本节记录的标准I/O的操作是在流进行的,当用标准I/O打开或创建一个文件时,已使一个流与一个文件相关联。

       标准I/O文件的流可用于单字节或多字节(宽)字符集。流的定向决定所读、写的字符是单字节还是多字节。流最初被创建时,并没有定向,若在未定向的流上使用一个多字节I/O函数,则将该流的定向设置为宽定向,若是使用一个单字节I/O函数,则将该流的定向设置为字节定向。只有两个函数可以改变流的定向:freopen函数清除一个流的定向;fwide函数设置流的定向。

/***********  * 设置流的定向  * 返回值:  *  1、若流是宽定向则返回正值;  *  2、若流是字节定向则返回负值;  *  3、若流是未定向则返回0;  * 函数原型:  * #include <stdio.h>  * #include <wchar.h>  * int fwide(FILE *fp, int mode);  * 说明:根据mode的不同值,fwide操作不同:  *  1、mode为负值,fwide试图使指定的流是字节定向;  *  2、mode为正值,fwide试图使指定的流是宽定向;  *  3、mode值为0,fwide不设置流的定向,返回标识该流定向的值;  * 注意:fwide并不改变已定向流的定向  * *************/  

5.3 标准输入、标准输出和标准出错

         对一个进程预定义了三个流,并且这三个流可以自动地被进程使用,他们是:标准输入、标准输出和标准出错。

/************  * 标准输入     stdin  * 标准输出     stdout  * 标准出错     stderr  * ***********/  

5.4 缓冲

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

/**************  * 缓冲:目的是减少数据的读写次数;  * 标准I/O的缓冲类型:  *  1、全缓冲:填满标准I/O缓冲区之后才进行实际I/O操作;  *  2、行缓冲:挡在输入和输出中遇到换行符,则执行I/O操作;  *  3、不带缓冲:标准I/O库不对字符进行缓冲存储;  *  * 函数功能:更改缓冲区类型  * 返回值:若成功则返回0,若出错则返回非0;  * 函数原型:  * #include <stdio.h>  * void setbuf(FILE *fp, char *buf);  * int setvbuf(FILE *fp,char *buf, int mode, ssize_t size);  * 注意:使用这两个函数必须确定fp流已经打开。  *  * setbuf函数打开或关闭缓冲机制,参数buf指定一个长度为BUFSIZE的缓冲区。  * sevbuf函数根据参数mode指定缓冲类型:  * mode参数:  *      _IOFBF  全缓冲  *      _IOLBF  行缓冲  *      _IONBF  不带缓冲  *____________________________________________________________  |函数   | mode   | buf    | 缓冲区及长度       | 缓冲类型    |  |_______|________|________|____________________|_____________|  |setbuf |        | 非空   | 长度BUFSIZE的buf   | 全或行缓冲  |  |       |        | NULL   | 无缓冲区           | 不带缓冲区  |  |_______|________|________|____________________|_____________|  |setvbuf| _IOFBF | 非空   | 长度size的buf      | 全缓冲      |  |       |        | NULL   | 合适长度缓冲区     |             |  |       | _IOLBF | 非空   | 长度size的buf      | 行缓冲      |  |       |        | NULL   | 合适长度的缓冲区   |             |  |       | _IONBF | 忽略   | 无缓冲区           | 不带缓冲区  |  |_______|________|________|____________________|_____________|  ********/  

标准I/O的文件操作是与流相关联的,所以我们要了解流的操作,下面记录的是流的基本操作,包括:流的打开、关闭、读和写操作。

5.5 打开流 

/* 函数功能:打开一个标准I/O流;  * 返回值:若成功返回文件指针,若出错返回NULL;  * 函数原型:  * #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);  * 说明:  * (1)fopen打开一个指定的文件pathname;  * (2)freopen在指定的流fp上打开一个指定的文件pathname,若流已经打开,则先关闭该流;  *      若该流已经定向,则freopen清除该流定向。  * (3)fdopen获取一个现有的文件描述符,并使一个标准I/O流与该文件描述符相结合。  *  * 参数type指定对该I/O的读、写方式:  * r或rb            为读而打开  * w或wb            把文件截短至0,或为写而创建  * a或ab            添加;为在文件尾写而打开,或为写而创建  * r+或r+b或rb+     为读和写而打开  * w+或w+b或wb+     把文件截短至0,或为读和写而打开  * a+或a+b或ab+     为在文件尾读和写而打开或创建  *  */ 

关闭一个已打开的流 

 /* * 函数功能:关闭一个已打开的流;  * 返回值:若成功则返回0,若出错则返回EOF;  * 函数原型:  * #include <stdio.h>  * int fclose(FILE *fp);  * *********************/  

5.6 读、写流 

/************  * 可用三种非格式化I/O对已打开的流进行读写:  *  (1)每次一个字符的I/O;一次读或写一个字符。  *  (2)每次一行的I/O;可用fgets和fputs读写,每行以换行符终止。  *  (3)直接I/O;可用fread和fwrite进行读写。  * 1、每次一个字符的I/O操作  *      输入函数  *  *      函数功能:读取一个字符;  *      返回值:若成功返回下一个字符,若已到达文件尾或出错则返回EOF;<stdio.h> 中的EOF值经常是-1 。 因为到达文件结尾和出错返回相同的值,为了区分这两种情况,需要下面的两个函数。ferror和feof 。 *      函数原型:  *      #include <stdio.h>  *      int getc(FILE *fp);  *      int fgetc(FILE *fp);  *      int getchar(void);  *      说明:  *      函数getchar等价于getc(stdin),前两个函数的区别是getc可被实现为宏,  *      而fgetc不能,则有以下区别:  *      (1)getc参数不能具有副作用的表达式;  *      (2)允许fgetc的地址作为一个参数传递给其它函数;  *      (3)调用fgetc所需时间比getc长,即函数调用时间长与宏调用;  *   在大多数实现中,为每个流在FILE 对象中维持了两个标志:出错标志和文件结束标志。 *     函数功能: 出错或文件结束标志  *     返回值:条件为真返回非0,否则返回0;  *     函数原型:  *     #include <stdio.h>  *     int ferror(FILE *fp); //出错返回非0 *     int feof(FILE *fp); //到达文件结尾,返回非0 *  *     void clearerr(FILE *fp);//清除出错和文件结束标志  *  *     输出函数  *  *     与输入函数对应有三个输出函数  *     函数功能:输出(写)一个字符;  *     返回值:若成功返回c,出错返回EOF;  *     函数原型:  *     #include <stdio.h>  *     int putc(int c, FILE *fp);  *     int fputc(int c, FILE *fp);  *     int putchar(int c);  *     说明:  *     putchar等价于putc(c,stdout)。putc可实现为宏,而fputc不能。  *  *     *********/  

5.7每次一行的流I/O操作 

 /*********  *  输入函数  *  *  函数功能:每次输入一行字符  *  返回值:若成功返回buf,若出错或已达到文件尾则返回NULL;  *  函数原型:  *  #include <stdio.h>  *  char *fgets(cahr *buf, int n, FILE *fp);  *  char *gets(char *buf, FILE *fp);  *  说明:  *  这两个函数都是将读入的行字符存储到缓冲区buf中。但是gets从标准输入读,  *  fgets从指定的流fp读。 另一个区别是gets 并不将换行符存入缓冲区中。 *  参数:  *  buf是缓冲区;  *  n是指定缓冲区的长度;  *  fp是文件流;  *  *  输出函数  *  *  函数功能:每次输出一行字符;  *  返回值:若成功返回非负值,若出错则返回EOF;  *  函数原型:  *  #include <stdio.h>  *  int fputs(const char *str, FILE *fp);  *  int puts(const char *str);  *     *********/  

5.8 标准 I/O 的效率

#include <stdio.h>  #include "apue.h"    int main(void)  {      char buf[MAXLINE];      while(fgets(buf,MAXLINE,stdin) != NULL)              if(fputs(buf,stdout) == EOF)              err_sys("out error.\n");      if(ferror(stdin))      err_sys("input error.\n");      exit(0);  }  

 5.9 二进制I/O 

/****  *  函数功能:读、写整个结构  *  返回值:读或写的对象数  *  函数原型:  *  size_t fread(void *ptr, size_t size, size_t nobj, FILE *fp);  *  size_t fwrite(void *ptr, size_t size, size_t nobj, FILE *fp);  *  说明:  *  ptr是读或写数据的起始位置;  *  size是数据结构的sizeof大小;  *  nobj是读或写的对象个数  *  fp是文件流;  *     *********/  

5.10 定位流

 有三种方法定位流:(1)ftell和fseek函数,他们假定文件的位置可存放在一个长整型中;(2)ftello和fseeko函数,他们使用off_t数据类型代替长整型;(3)fgetpos和fsetpos函数,他们使用一种抽象的数据类型fpos_t记录文件的位置;/*********   * 定位流   * 有三种方法定位流:   * 1、ftell和fseek函数,他们假定文件的位置可存放在一个长整型中;   * 2、ftello和fseeko函数,他们使用off_t数据类型代替长整型;   * 3、fgetpos和fsetpos函数,他们使用一种抽象的数据类型fpos_t记录文件的位置;   *   * 函数原型:   * #include <stdio.h>   * long ftell(FILE *fp)//若成功返回当前文件位置的指示,出错返回-1L;   * int fseek(FILE *fp, long offset, int whence);//若成功返回0,出错返回非0;   * 说明:   * 对于二进制文件,其文件位置指示器是从文件起始位置开始度量,并以字节为计量单位;   * 参数:   * offset是偏移量;   * whence的值与lssek函数的参数值一样:SEEK_SET起始位置,SEEK_CUR当前位置,SEEK_END尾端;   *   * #include <stdio.h>   * off_t ftello(FILE *fp);//若成功返回当前文件位置指示,出错返回-1   * int fsseko(FILE *fp, off_t offset, int whence);//若成功则返回0,出错返回非0   * 除了offset的类型是off_t而非long以外,ftello与ftell相同,fseeko与fseek相同;   *   * int fgetpos(FILE *fp, fpos_t *pos);   * int fsetpos(FILE *fp, const fpos_t *pos);   * 返回值:两函数若成功则返回0,出错返回非0值;   *   * ****/  


 

0 0
原创粉丝点击