在第3章中,所有I/O函数都是围绕文件描述符的。当打开一个文件时,即返回一个文件描述符,然后该文件描述符就用于后续的I/O操作。而对于标准I/O库,它们的操作时围绕流(stream)进行的(请勿将标准I/O术语与System V的STREAMS I/O系统相混淆,STREAMS I/O系统是System V的组成部分,Single UNIX Specification则将其标准化为XSI STREAMS 选项,但是SUSv4中已经将其标记为弃用)。当用标准I/O库打开或创建一个文件时,我们已使一个流与一个文件相关联。
对于ASCII字符集,一个字符用一个字节表示。对于国际字符集,一个字符可用多个字节表示。标准I/O文件流可用于单字节或多字节(“宽”)字符集。流的定向(stream's orientation)决定了所读、写的字符时单字节还是多字节的。当一个流最初被创建时,它并没有定向。如若在未定向的流上使用一个多字节I/O函数(见<wchar.h>),则将该流的定向设置为宽定向的。若在未定向的流上使用一个单字节I/O函数,则将该流的定向设为字节定向的。只有两个函数可改变流的定向。freopen函数(稍后讨论)清除一个流的定向;fwide函数可用于设置流的定向。
#include <stdio.h> #include <wchar.h> int wide(FILE *fp, int mode); 返回值:若流是宽定向的,返回正值;若流是字节定向的,返回负值;若流是未定向的,返回0 |
根据mode参数的不同值,fwide函数执行不同的工作。
- 如若mode参数值为负,fwide将试图使指定的流是字节定向的。
- 如若mode参数值为正,fwide将试图使指定的流是宽定向的。
- 如若mode参数为0,fwide将不试图设置流的定向,但返回表示该流定向的值。
注意,fwide并不改变已定向流的定向。还应注意的是,fwide无出错返回。试想,如若流是无效的,那么将发生什么呢?我们唯一可依靠的是,在调用fwide前先清除errno,从fwide返回时检查errno的值。在本书的其余部分,我们只涉及字节定向流。
当打开一个流时,标准I/O函数fopen(参考5.5节)返回一个指向FILE对象的指针。该对象通常是一个结构,它包含了标准I/O库为管理该流需要的所有信息,包括用于实际I/O的文件描述符、指向用于该流缓冲区的指针、缓冲区的长度、当前在缓冲区中的字符数以及出错标志等。
应用程序没有必要检验FILE对象。为了引用一个流,需将FILE指针作为参数传递给每个标准I/O函数。在本书中,我们称指向FILE对象指针(类型为FILE *)为文件指针。
在本章中,我们在UNIX系统环境中说明标准I/O库。正如前述,此标准库已移植到UNIX之外的很多系统中。但是为了说明该库实现的一些细节,我们将讨论其在UNIX系统上的典型实现。