本章学习ISO C,和一般C语言书籍中的内容大同小异,不过加入了Unix一些特有的扩展。
流
#include <stdio.h>
#include <wchar.h>
int fwide(FILE *fp, int mode);
若mode=0,该函数确定流是否使用了宽字符集(注意不是Unicode),宽定向返回正值,字节定向返回负值,未定向返回0;
如果流未定向,也可以使用mode参数将之定向;但该函数并不能改变已定向流的定向。freopen函数可以清除流的定向。
缓冲
标准I/O提供了3种缓冲方式:无缓冲、行缓冲和全缓冲,在典型标准流实现中,stderr是无缓冲的,与终端相连时是行缓冲的,其他基本是全缓冲的(但标准并未强行规定)
改变缓冲方式的函数:
#include <stdio.h>
void setbuf(FILE *restrict fp,char *restrict buf);
int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);\
在文件打开后,传入FILE指针,将buf指向一个长度为BUFSIZ大小的缓冲区,然后第一个函数就可以将流设置为全缓冲的;
第二个函数则可以通过设置mode值来制定缓冲方式——_IOFBF(全),_IOLBF(行),_IONBF(无),buf指向缓冲区,size则确定缓冲区大小;如果buf是NULL,缓冲区会自动分配。
刷新流:fflush,即刻将指定文件缓冲区中的数据写入内核;如果参数时null,则刷新所有流。
打开流
fopen,freopen
FILE *fdopen(int filedes,const char *type); //SUS
freopen主要用于在一个指定的流上打开指定的文件;
fdopen是SUS扩展函数,参数为文件描述符,作用是将文件描述符转为FILE函数,
这里在type中使用了'+'打开时有一些限制,注意最好在任意的写和读之间刷新流,在读和写之间重定位偏移量。
读写流
基于字符的读写:fgetc,getc,getchar;fputc,putc,putchar;ungetc
基于行的读写:fgets,gets;fputs,puts
二进制读写:fread, fwrite;这两个函数不能用于网络传输数据,或跨平台读写。
定位流
ftell, fseek
ftello,fseeko //SUS
fgetpos, fsetpos
第一组数据假设偏移量可以用long表示;第二组偏移量类型是off_t,第三组是fpos_t
格式化I/O
即printf系和scanf系
SUS扩展
int fileno(FILE *fp);这个函数可以将FILE指针转回文件描述符
临时文件
char *tmpnam(char *ptr); //生成临时路径
FILE *tmpfile(); //临时文件,生成打开后会立刻unlink
char *tempnam(const char *dir, const char *prefix); //SUS,临时路径,dir指定目录,但是并非第一优先序列;目录寻找顺序为TMPDIR,dir,P_tmpdir <stdio.h>和/tmp;prefix为文件名指定前缀
int mkstemp(char *template); //SUS <stdlib.h>,临时文件,返回文件描述符,名字由参数指定,需要自行删除
标准I/O的缺点
效率偏低,有替代版本。