标准 I/O 函数

对于标准 I/O 库,它们的操作是围绕流(stream)进行的。当用标准 I/O 库打开或创建一个文件时,我们已使一个流与一个文件相关联。

函数 fwide 设置流的定向

#include <stdio.h>
#include <wchar.h>

int fwide(FILE *fp, int mode);
/* 返回值:
    若流是宽定向的,返回正值
    若流是字节定向的,返回负值
    若流是未定向的,返回0
*/

流的定向:决定了所读、写的字符是单字节或多字节(“宽”)的。当一个流最初被创建时,它并没有定向。若在未定向的流上使用一个多字节的 I/O 函数,则将该流的定向设置为宽定向的。若在未定向的流上使用一个单字节的 I/O 函数,则将该流的定向设为字节定向的。

缓冲

标准 I/O 库提供缓冲的目的是尽可能减少使用 read 和 write 调用的次数。一共提供了以下三种缓冲

全缓冲:在这种情况下,在填满标准 I/O 缓冲区后才进行实际 I/O 操作。

行缓冲:当在输入和输出中遇到换行符时,标准 I/O 库执行 I/O 操作。

不带缓冲:标准 I/O 库不对字符进行缓冲存储。

标准错误流 stderr 通常时不带缓冲的,这就使得出错信息可以尽快显示出来,而不管它们是否含有一个换行符。

很多系统默认使用下列类型的缓冲:

  • 标准错误时不带缓冲的
  • 若是指向终端设备的流,则是行缓冲的;否则时全缓冲的。

函数 setbuf 和 setvbug 更改缓冲类型 

#include <stdio.h>

void setbuf(FILE *restrict fp, char *restrict buf);

int setvbuf(FILE *restrcit fp, char *restrict buf, int mode, size_t size);
// 返回值:若成功,返回 0;若出错,返回非 0

因为每个函数都要求一个有效的文件指针作为它们的第一个参数,所以这些函数一定要在流已被打开后调用。

setbuf 函数打开或关闭缓冲机制:为了带缓冲进行 I/O,参数 buf 必须指向一个长度为 BUFSIZ 的缓冲区(该常量定义在<stdio.h>中),通常设置之后该流就是全缓冲的,但是如果该流是与一个终端设备相关,那么有些系统可能将其设置为行缓冲。为了关闭缓冲,则需要将 buf 设置为 NULL。

setvbuf 可以精确的说明所需的缓冲类型,用 mode 参数实现:

_IOFBF         全缓冲

_IOLBF         行缓冲

_IONBF         不带缓冲

如果指定一个不带缓冲的流,则忽略 buf 和size 参数。如果指定全缓冲或行缓冲,则 buf 和 size 可选择地指定一个缓冲区及其长度。如果该流本身是带缓冲的,而 buf 是 NULL,则标准 I/O 库将自动地为该流分配适当长度的缓冲区(即 常量 BUFFSIZ 所指的值)。

函数 fflush 冲洗一个流

在 UNIX 环境中,flush 有两种意思,在表中 I/O 库方面,flush(冲洗)意味着将缓冲区中的内容写到磁盘上(该缓冲区可能至少部分填满的)。在终端驱动程序方面,flush(刷清)表示丢弃已存储在缓冲区中的数据。

任何时候,都可以使用 fflush 强制冲洗一个流。

#include <stdio.h>

int fflush(FILE *fp);
// 返回值:若成功,返回0;若出错,返回 EOF

此函数是该流所有未写的数据都被传送至内核。作为一种特殊情形,如若 fp 是 NULL,则此函数将导致所有输出流被冲洗。

打开流函数 fopen、freopem 和 fdopen

#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, chonst char *type);

// 返回值:若成功,返回文件指针,若出错,返回 NULL

这 3 个函数的区别如下:

  1. fopen 函数打开路径名为 pathname 的一个指定的文件。
  2. freopen 函数在一个指定的流上打开一个指定的文件,如若该流已经打开,则先关闭该流。若该流已经定向,则使用 freopen 清楚该定向。此函数一般用于将一个指定的文件打开为一个预定义的流:标准输入、标准输出或标准错误。
  3. fdopen 函数取一个已有的文件描述符,并使一个标准的 I/O 流与该描述符相结合。此函数常用于有创建管道和网络通道函数返回的描述符。因为有些特殊类型的文件不能用标准 I/O 函数 fopen 打开(比如 socket),所以我们必须先调用设备专用函数以获得一个文件描述符,然后用 fdopen 使一个标准 I/O 流与该描述符相结合。

type参数指定对该 I/O流的读、写方式

r 或 rb                        为读而打开

w 或 wb                     为写而创建或把文件截断至 0 长

a 或 ab                       追加:为在文件尾写而打开,或为写而创建

r+ 或 r+b 或 rb+         为读和写而打开

w+ 或 w+b 或 wb+     为读和写而打开或把文件截断至 0 长

a+ 或 a+b 或 ab+        为在文件尾读和写而打开或创建

使用字符 b 作为 type 的一部分,这使得标准版 I/O 系统可以区分文本文件和二进制文件。

对于 fdopen 为写而打开并不截断该文件。

注:在指定 w 或 a 类型创建一个新文件时,我们无法说明该文件的访问权限位。可以通过挑中 umask 值来限制这些权限。 此外,除非流引用终端设备,否则按系统默认,流被打开时是全缓冲的。若流引用终端设备,则该流是行缓冲的。

函数 fclose 关闭一个打开的流

#include <stdio.h>

int fclose(FILE * fp);
// 返回值:若成功,返回 0;若出错,返回 EOF

在该文件关闭之前,冲洗缓冲区的输出数据。缓冲区的任何输入数据被丢弃。如果标准 I/O 库已经为该流自动分配了一个缓冲区,则释放此缓冲区。

  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值