[APUE]标准IO库(上)
一、流和FILE对象 ASSI C要求以下缓存特征: #include <stdio.h> void setbuf(FILE *fp,char *buf); int setvbuf(FILE *fp,1)">char *buf,1)">int mode,size_t size); 这些函数必须在流打开后和对该流进行任何操作之前调用。 _IOFBF 全缓存
_IOLBF 行缓存,_IONBF 不带缓存
如果指定了一个不带缓存的流,则忽略buf和size参数。如果指定全缓存或行缓存,则buf和size可以选择地指定一个缓存及长度。如果该流是带缓存的,而buf是NULL,则标准IO库将自动的为该流分配适当长度的缓存,适当长度是指struct stat结构体中的st_blksize所指定的值。如果系统不能为为该流决定此值(例如该流涉及一个设备或一个管道),则分配长度为BUFSIZ的缓存。
如果在一个函数中分配了一个自动变量类的标准IO缓存,则从该函数返回之前必须关闭该流。SVR4将缓存的一部分用于ta自己的管理操作,所以可以存放在缓存中的实际数据字节数小于size。一般来说,应由系统选择缓存的长度,并自动分配缓存。在这样处理时,标准IO库在关闭此流时将自动关闭释放缓存。 #include <stdio.h>
int fflush(FILE *fp);
此函数使该流所有的数据传递到内核,如果fp是NULL,则此函数刷新所有输出流。 三、打开流 #include <stdio.h> FILE *fopen(const char *pathname,1)">type); FILE *freopen(type,FILE fp); FILE *fdopen(int fileds,1)">type); 返回值: 成功文件指针,失败NULL 三个函数的区别: (1)fopen打开路径为pathname的文件。 使用字符b作为type的一部分使得标准IO系统可以区分文本文件或二进制文件。因为UNXI并不对这两种文件区分所以在UNIX环境下指定b作为type的一部分实际上并无作用。
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH 除非流引用终端设备,否则按系统默认,它被打开时是全缓存。若流引用终端设备则该流是行缓存。 #include <stdio.h> int fclose(FILE *fp); 返回值: 成功0,出错EOF 在该文件关闭之前,刷新缓存中的输出数据。缓存中的输入数据被丢弃。如果标准IO库已经为该流自动分配了一个缓存则释放该缓存。 四、读和写流 直接IO(direct IO)这个术语来自ANSI C标准,有时也被称为:二进制IO、一次一个对象IO、面向记录的IO或面向结构的IO。 1.输入函数 #include <stdio.h> int getc(FILE *fp); int fgetc(FILE *int getchar(void); 返回值:成功则为下一个字符,如果已处于文件尾端或出错则为EOF getchar等同于getc(stdin)。前两个函数的区别是getc可被实现为宏,而fgetc则不能。(这里的可被实现为宏即大多数UNIX系统中getc的实现是这样:在<stdio.h>中#define getc(FILE *fp) xxx(FILE *fp),即getc不是一个函数而是一个宏)这意味着: 这三个函数以unsigned char类型转换为int的方式返回下一个字符。返回int的原因是函数可以返回一个负值(指示出错或已到达文件尾端),在<studio.h>中常数EOF常要求是一个负值,其值经常是-1。所以不能将这三个函数的返回值放到一个字符变量中。 不管是出错还是到达文件尾端,这三个函数都返回同样的值。为了区分这两种不同的情况,须调用ferror或feof。 #include <stdio.h> int ferror(FILE *int feof(FILE *fp); 返回值:条件为真返回非0值,否则0 void clearerr(FILE *fp); 在大多数实现的FILE对象中,为每个流保持了两个标志
从一个流读之后,可以调用ungetc将字符再送回到流中。 #include <stdio.h> int ungetc(int c,FILE *fp); 送回到流中的字符又可以从流中读出,但读出字符的顺序与送回的顺序相反。回送的字符不一定是上一次读到的字符。EOF不能回送。但是当已到达文件尾端时仍可以回送一个字符。下次读将返回该字符,再次读则返回EOF。之所以可以这样做的原因是一次成功的ungetc调用会清除该流的文件结束指示。 当正在读一个输入流,并进行某种形式的分字或分记号操作时,会经常用到回送字符操作。有时需要先看一看下一个字符以决定如何处理当前字符。然后就需要方便的将刚查看的字符送回,以便下一次调用getc时返回该字符。 ? 2. 输出函数
#include <stdio.h> int putc(int fputc(int putchar(int c); 返回值:成功返回c,出错EOF putchar等同于putc(c,stdout) ? 五、 每次一行IO 下面两个函数提供每次输入一行的功能: #include <stdio.h> char *fgets(int n,1)">char *buf); gets从标准输入读。对于fgets必须指定缓存buf的长度n。此函数会一直读到下一个新行符为止,但是不超过n-1个字符,读入的字符被送入到缓存。该缓存以null字符结尾。如果该行包括最后一个新行符的字符数超过n-1,则只返回一个不完整的行,而且缓存总是以null字符结尾。对fgets的下一次调用会继续该行。 gets函数不被推荐使用因为不能指定缓存的长度,gets并不将新行符存入缓存中。 #include <stdio.h> int fputs(char *str,1)">int puts(char *str); 函数fputs将一个以null符终止的字符串写入到指定的流,终止符null不写出。这并不一定是每次输出一行,因为它并不要求在null符之前一定是新行符,但是通常在null符之前是一个新行符。 puts将一个以null符终止的字符串写入到标准输出,终止符不写出。但是puts然后将一个新行符写到标准输出。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |