C/C++——文件输入输出
头文件
<stdio.h>
头文件提供通用文件支持并提供有窄字符输入/输出能力的函数。
<wchar.h>
头文件提供有宽字符输入/输出能力的函数。
I/O 流
I/O 流是 FILE 类型对象,只能通过 FILE* 类型指针访问及操作(注意:在可能通过解引用合法的 FILE* 复制创建 FILE 类型局部对象时,在 I/O 函数使用这种副本的地址是未定义行为)。每个流与外部物理设备(文件、标准输入流、打印机、序列端口等)关联。
I/O 流能用于无格式和有格式的输入及输出。它们对本地环境敏感,并可在需要时提供宽/多字节转换。所有流都访问同一本地环境对象:最近 setlocale 所安装者。
在系统指定的需要访问设备的信息(例如 POSIX 文件描述符)外,每个流对象保有下列信息:
- (C95)字符宽度:未设置、窄或宽。
- 缓冲状态:无缓冲、行缓冲、全缓冲。
- 缓冲区,可为外部的用户提供缓冲区所替换。
- I/O 模式:输入、输出或更新(兼具输入与输出)。
- 二进制/文本模式指示器。
- 文件尾指示器。
- 错误状态指示器。
- 文件位置指示器( fpos_t 类型对象),对于宽字符流包含剖析状态( mbstate_t 类型对象(C95))。
- (C11)在多个线程读、写、寻位或查询流时避免数据竞争的再入锁。
窄与宽面向
新打开的流无面向。首次到 fwide 的调用或 I/O 函数建立面向:宽 I/O 函数令流为宽面向,窄 I/O 函数令流为窄面向。一旦设置,则面向只能以 freopen 更改。不能在宽面向流上调用窄 I/O 函数,不能在窄面向流上调用宽 I/O 函数。宽 I/O 函数在宽与多字节字符间如同以调用 mbrtowc 和 wcrtomb 转换。不同于程序中合法的多字节字符串,文件中的多字节字符可以含有嵌入的空字符且不必以初始迁移状态开始或结束。
POSIX 要求在流对象的面向变成宽时,将当前安装的 C 本地环境的 LC_CTYPE 平面存储于其中,而且将它用于此流上的所有将来 I/O 直至面向被更改,无关乎任何到 setlocale 的后继调用。
二进制与文本模式
文本流是被组合进行(零或更多字符加上终止的 '\n' )的有序字符序列。最后一行是否要求终止的 '\n' 是实现定义的。可能必须在输入与输出时添加、切换或删除字符,以符合 OS 中的表示文本(尤其是 Windows OS 上的 C 流在输出时将 \n
转换为 \r\n
,输入时将 \r\n
转换为 \n
)。
仅若下列条件全为真,从文本流读取的数据才保证与先前写出到该文本流者比较相等:
- 数据只由打印字符和控制字符
\t
及\n
组成(尤其是 Windows OS 上,字符'\0x1A'
终止输入)。 - 没有 \n 立即为空格符所前趋(立即先于 \n 写入的空格符可能在读取时消失)。
- 末字符是 \n 。
二进制流是能通透地记录内部数据的有序字符序列。从二进制流读取的数据始终与先前写出到该流者比较相等。仅允许实现后附一些空字符到流结尾。宽二进制流不必终止于初始迁移状态。
POSIX 实现不辨别文本与二进制流(无 \n 或任何其他字符的特殊映射)。
函数
文件访问
文件访问 |
||
定义于头文件
<stdio.h> |
||
(C11) |
FILE *fopen( const char *filename, const char *mode );
|
打开文件 (函数) |
(C11) |
以不同名称打开既存的文件流 (函数) |
|
关闭文件 (函数) |
||
将输出流与实际文件同步 (函数) |
||
为文件流设置缓冲区 (函数) |
||
为文件流设置缓冲区和其大小 (函数) |
||
定义于头文件
<wchar.h> |
||
(C95)
|
将文件流在宽字符I/O和窄字符I/O间切换 (函数) |
|
直接输入/输出 |
||
定义于头文件
<stdio.h> |
||
从文件读取 (函数) |
||
写入到文件 (函数) |
||
无格式输入/输出 |
||
窄字符 |
||
定义于头文件
<stdio.h> |
||
从文件流获取一个字符 (函数) |
||
从文件流获取一个字符串 (函数) |
||
将一个字符写入文件流 (函数) |
||
将一个字符串写入文件流 (函数) |
||
从 stdin 读取一个字符 (函数) |
||
(C11 中移除)
(C11 起) |
从 stdin 读取一个字符串 (函数) |
|
将一个字符写入 stdout (函数) |
||
将一个字符串写入 stdout (函数) |
||
将一个字符送回文件流 (函数) |
||
宽字符 |
||
定义于头文件
<wchar.h> |
||
(C95)
|
从文件流获取一个宽字符 (函数) |
|
(C95)
|
从文件流获取一个宽字符串 (函数) |
|
(C95)
|
将一个宽字符写入文件流 (函数) |
|
(C95)
|
将一个宽字符串写入文件流 (函数) |
|
(C95)
|
从 stdin 读取一个宽字符 (函数) |
|
(C95)
|
将一个宽字符写入 stdout (函数) |
|
(C95)
|
将一个宽字符送回文件流 (函数) |
|
有格式输入/输出 |
||
窄字符 |
||
定义于头文件
<stdio.h> |
||
(C11) (C11) (C11) |
从stdin、文件流或缓冲区读取格式化输入 (函数) |
|
(C99)
(C99) (C99) (C11) (C11) (C11) |
从 stdin 、文件流或缓冲区读取格式化输入 使用可变参数列表 (函数) |
|
(C99) (C11) (C11) (C11) (C11) |
打印格式化输出到 stdout 、文件流或缓冲区 (函数) |
|
(C99) (C11) (C11) (C11) (C11) |
打印格式化输出到stdout、文件流或缓冲区 使用可变参数列表 (函数) |
|
宽字符 |
||
定义于头文件
<wchar.h> |
||
(C95)
(C95) (C95) (C11) (C11) (C11) |
从stdin、文件流或缓冲区读取格式化宽字符输入 (函数) |
|
(C99)
(C99) (C99) (C11) (C11) (C11) |
从stdin、文件流或缓冲区读取格式化宽字符输入 使用可变参数列表 (函数) |
|
(C95)
(C95) (C95) (C11) (C11) (C11) (C11) |
打印格式化宽字符输出到stdout、文件流或缓冲区 (函数) |
|
(C95)
(C95) (C95) (C11) (C11) (C11) (C11) |
打印格式化宽字符输出到 stdout 、文件流或缓冲区 使用可变参数列表 (函数) |
|
文件位置 |
||
定义于头文件
<stdio.h> |
||
返回当前的文件位置指示值 (函数) |
||
获取文件位置指示器 (函数) |
||
将文件位置指示符移动到文件中的指定位置 (函数) |
||
将文件位置指示器移动到文件中的指定位置 (函数) |
||
将文件位置指示器移动到文件首 (函数) |
||
错误处理 |
||
定义于头文件
<stdio.h> |
||
清除错误 (函数) |
||
检查文件结尾 (函数) |
||
检查文件错误 (函数) |
||
显示对应当前错误的字符串到 stderr (函数) |
||
文件操作 |
||
定义于头文件
<stdio.h> |
||
删除文件 (函数) |
||
重命名文件 (函数) |
||
(C11) |
返回指向临时文件的指针 (函数) |
|
(C11) |
返回唯一的文件名 (函数) |
类型
定义于头文件
<stdio.h> |
|
类型 | 定义 |
FILE | 类型,足以保有所有 C I/O 流所需的信息 |
fpos_t | 类型,足以唯一指定文件的位置和多字节剖析状态 |
宏
定义于头文件
<stdio.h> |
|
stdin
stdout stderr |
与标准输入流关联的 FILE* 类型表达式 与标准输出流关联的 FILE* 类型表达式 与标准错误输出流关联的 FILE* 类型表达式 (宏常量) |
EOF
|
int 类型的负值整数常量表达式 (宏常量) |
FOPEN_MAX
|
能同时打开的文件数 (宏常量) |
FILENAME_MAX
|
保有最长受支持文件名所需的字符数组大小 (宏常量) |
BUFSIZ
|
setbuf()所用的缓冲区大小 (宏常量) |
_IOFBF
_IOLBF _IONBF |
指示全缓冲 I/O 的 setvbuf() 参数 指示行缓冲 I/O 的 setvbuf() 参数 指示无缓冲 I/O 的 setvbuf() 参数 (宏常量) |
SEEK_SET
SEEK_CUR SEEK_END |
指示从文件首开始寻位的 fseek() 参数 指示从文件当前位置开始寻位的 fseek()参数 指示从文件尾开始寻位的 fseek() 参数 (宏常量) |
TMP_MAX
TMP_MAX_S (C11) |
tmpnam 所能生成的最大独有文件数 tmpnam_s 所能生成的最大独有文件数 (宏常量) |
L_tmpnam
L_tmpnam_s (C11) |
保有 tmpnam 结果所需的数组大小 保有 tmpnam_s 结果所需的数组大小 (宏常量) |