第五章-标准I/O库

一、流和FILE对象

第三章中,所有I/O函数都是围绕文件描述符的。当打开一个文件,即返回一个文件描述符,然后该fd用于后续I/O操作。
而对于标准I/O库,它们的操作是围绕流(stream)进行的。当使用标准I/O库打开或创建一个文件时,我们已使一个流与一个文件相关联。流的定向(orientation)决定了所读、写的字符是单字节还是多字节的。如若在未定向的流上使用一个多字节I/O函数,则改流的定向设置为宽定向的;若使用单字节I/O函数,则为字节定向。
以下两个函数用于改变流的定向。
freopen清除流定向(后续介绍),fwide设置流的定向:

#include <stdio.h>
#include <wchar.h>
int fwide(FILE* fp, int mode);

若流为宽定向,返回正;字节定向,返回负;未定向,返回0;
mode参数:正,试图设为宽定向;负,试图设为字节定向;0,不试图设置流的定向。
FILE: 当打开一个流时,标准I/O函数fopen返回一个指向FILE对象的指针。该对象包含了标准I/O库为管理该流所需要的所有信息。

二、缓冲

标准I/O库提供缓冲的目的是尽量减少read和write的调用次数。标准库提供了以下三种类型的缓冲:
(1)全缓冲。填满标准I/O缓冲区后才进行实际I/O操作。在一个流上执行第一次I/O操作时,相关标准I/O函数通常调用malloc获得需使用的缓冲区。
flush:标准I/O缓冲区的写操作。缓冲区可由标准I/O例程自动冲洗(例如,当填满一个缓冲区时),或者调用函数fflush冲洗一个流。

#include <stdio.h>
int fflush(FILE* fp);

此函数使该流所有未写数据都被传送至内核。若fp是NULL,则导致所有输出流均被冲洗。

(2)行缓冲。当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。当流涉及一个终端是(标准输入输出),通常使用行缓冲。
(3)不带缓冲。标准I/O库不对字符进行缓冲存储。标准错误流stderr通常是不带缓冲的,这就使得出错信息可以尽快显示出来,而不管是否有换行符。
ISO C标准/惯例:
标准错误不带缓冲;打开至终端设备的流是行缓冲的;其他流是全缓冲的。
以下函数用于更改缓冲类型:

#include <stdio.h>
void setbuf(FILE* restrict fp, char* restrict buf);
void setvbuf(FILE* restrict fp, char* restrict buf, int mode, size_t size);

成功返回0,失败返回非0;要在流已被打开后调用(第一个参数就是有效的FILE指针)。
可以使用setbuf函数打开或关闭缓冲机制。为了带缓冲进行I/O,参数buf必须指向一个长度为BUFSIZ的缓冲区(此后就是全缓冲)。为了关闭缓冲,将buf设为NULL。
使用setvbuf,可精确说明所需的缓冲类型。即mode参数
_IOFBF 全缓冲
_IOLBF 行缓冲
_IONBF 不带缓冲

三、打开、读和写流

3.1 打开流

打开标准I/O流:

#include <stdio.h>
FILE* fopen(const char* restrict pathname, const char* restrict type);
FILE* freopen(const char* restrict pathname, const char* restrict type, FILE* restrict fp);
FILE* fdopen(int fd, const char* type);

成功,返回FILE*;失败,返回NULL

  • fopen:打开指定文件
  • freopen:在一个指定的流上打开一个指定的文件,若改流已经打开,则先关闭该流。若该流已经定向,则使用freopen清除该定向。此函数一般用于将一个指定的文件打开为一个预定的流:标准输入、标准输出或标准错误。
  • fdopen:取一个已有的文件描述符,并使一个标准I/O流与该描述符相结合。
    调用fclose关闭一个打开的流:
#include <stdio.h>
int fclose(FILE* fp);

该文件被关闭之前,冲洗缓冲区中的输出数据,输入数据被丢弃。释放缓冲区

3.2 读写流

三种非格式化I/O(格式化I/O如printf,scanf),对流进行读写:
(1)每次一个字符的I/O。若流是带缓冲的,则标准I/O函数处理所有缓冲
(2)每次一行的I/O。使用fgets和fputs。每行都以一个换行符终止
(3)直接I/O。fread和fwrite。每次I/O操作读或写某种数量的对象

3.2.1 输入函数
  • 以下三个函数可用于一次读一个字符
#include <stdio.h>
int getc(FILE* fp);
int fgetc(FILE* fp);
int getchar(void);

成功,返回下一个字符;到达文件尾或出错,返回EOF。

  • 以下三个函数可用于一次输入一行
#include <stdio.h>
char* gets(char* buf);
char* fgets(char* restrict buf, int n, FILE* restrict fp);

成功,返回buf;到达文件尾或出错,返回NULL。

两个函数都指定了缓冲区的地址。将读入的行送入其中。gets从标准输入读,而fgets从指定的流读。

3.2.2 输出函数
  • 一次输出一个字符
#include <stdio.h>
int putc(int c, FILE* fp);
int fputc(int c, FILE* fp);
int putchar(int c);
  • 每次输出一行
#include <stdio.h>
char* puts(const char* str);
char* fputs(const char* restrict str, FILE* restrict fp);

四、二进制I/O

五、定位流

六、格式化I/O

七、实现细节

八、临时文件

九、内存流

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值