代码改变世界

C语言标准IO

2012-07-27 16:00  iamzhaiwei  阅读(1502)  评论(0编辑  收藏  举报
这几天参加中兴捧月比赛,用到了C语言的标准IO库。由于对其中的一些细节不是非常清楚,导致了许多Bug,花了好长时间来调试。所以在此做个笔记,以备后查。

1. 缓冲区
全缓冲。在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。对驻留在磁盘上的文件的访问通常是由标准I/O库实施全缓冲的。 缓冲区可由标准IO例程自动冲洗(如当填满一个缓冲区时),或调用函数fflush强制冲洗
行缓冲。在这种情况下,当在输入和输出中遇到新行符时,标准I/O库执行I/O操作,这允许我们一次输出一个字符(如fputc函数),但只有写了一行之后才进行实际I/O操作。当流涉及一个终端时(例如标准输入和标准输出),典型地使用行缓冲。
不带缓冲。标准I/O库不对字符进行缓冲。如果用标准I/O函数写若干字符到不带缓冲的流中,则相当于用write系统调用将这些字符写到打开的文件上。标准出错况stderr通常是不带缓存的,这就使得出错信息可以尽快显示出来。

2. 打开流
FILE *fopen(const char *filename, const char *type)
若成功,返回文件指针;若失败,返回NULL

这里要注意参数type对打开的流的读写的影响。
type 说明
r    为只读而打开;文件必须存在
w    为只写而新建;若文件已存在,将文件内容截短至0
a    为在文件尾端添写而打开;若文件不存在,新建
r+    为读写而打开;文件必须存在
w+    为读写而新建;若文件已存在,将文件内容截短至0
a+    为在文件尾端读和写而打开;若文件不存在,新建。可通过fseek或rewind重定位文件指针位置来读,但写操作将把文件指针移回到文件尾端

使用字符b作为type的一部分,可以区分文本文件和二进制文件。但有些系统不作区分,如UNIX。

当以读写方式打开文件时,即type中有“+”时,在输出操作和输入操作之间一定要有冲洗fflush或重定位fseek、fsetpos、rewind等操作。

3. 关闭流
int fclose(FILE *fp)
关闭流之前,冲洗缓冲区中的输出数据,丢弃缓冲区中的任何输入数据。
进程正常终止时,所有带未写缓冲数据的流被冲洗,所有的流被关闭。异常终止时,不保证冲洗缓冲区。

4. 二进制IO
size_t fread(void *buf,        size_t size, size_t count, FILE *fp);
size_t fwrite(const void *buf, size_t size, size_t count, FILE *fp);
返回读写的对象数。
限制:只能用于读在同一系统上已写的数据。

参考资料:
APUE