C++ 标准库的 C I/O 子集实现 C 风格流输入/输出操作。 <cstdio>
头文件提供通用文件支持并提供有窄和多字节字符输入/输出能力的函数,而 <cwchar>
头文件提供有宽字符输入/输出能力的函数。
C 流是 std::FILE 类型对象,只能通过 std::FILE* 类型指针访问及操作(注意:在可能以解引用合法的 std::FILE* ,复制创建 std::FILE 类型的局部对象时,在 I/O 函数使用这种副本的地址是未定义行为)。每个 C 流与外部物理设备(文件、标准输入流、打印机、序列端口等)关联。
C 流能用于无格式和有格式的输入及输出。它们对本地环境敏感,并可在需要时提供宽/多字节转换。不同于关联到其自身本地环境的 C++ 流,所有 C 流都访问同一本地环境对象:最近 std::setlocale 所安装者。
除了访问设备所必须的系统限定信息(例如 POSIX 文件描述符),每个 C 流对象保有以下内容:
1) 字符宽度:未设置、窄或宽。
2) 缓冲状态:无缓冲、行缓冲、全缓冲。
3) 缓冲区,可为外部的用户提供缓冲区所替换。
4) I/O 模式:输入、输出或更新(兼具输入与输出)。
5) 二进制/文本模式指示器。
6) 文件尾指示器。
7) 错误状态指示器。
8) 文件位置指示器( std::fpos_t
类型对象),对于宽字符流包含剖析状态( std::mbstate_t 类型对象)。
9) (C++17)在多个线程读、写、寻位或查询流时避免数据竞争的再入锁。
窄与宽面向
新打开的流无面向。首次到 std::fwide 的调用或 I/O 函数建立面向:宽 I/O 函数令流为宽面向,窄 I/O 函数令流为窄面向。一旦设置,则面向只能以 std::freopen 更改。不能在宽面向流上调用窄 I/O 函数,不能在窄面向流上调用宽 I/O 函数。宽 I/O 函数在宽与多字节字符间如同以调用 std::mbrtowc 和 std::wcrtomb 转换。不同于程序中合法的多字节字符串,文件中的多字节字符可以含有嵌入的空字符且不必以初始迁移状态开始或结束。
POSIX 要求在流对象的面向变成宽时,将当前安装的 C 本地环境的 LC_CTYPE 平面存储于其中,而且将它用于此流上的所有将来 I/O 直至面向被更改,无关乎任何到 std::setlocale 的后继调用。
二进制与文本模式
文本流是被组合进行(零或更多字符加上终止的 '\n' )的有序字符序列。最后一行是否要求终止的 '\n' 是实现定义的。可能必须在输入与输出时添加、切换或删除字符,以符合 OS 中的表示文本(尤其是 Windows OS 上的 C 流在输出时将 \n
转换为 \r\n
,输入时将 \r\n
转换为 \n
)。
仅若下列条件全为真,从文本流读取的数据才保证与先前写出到该文本流者比较相等:
- 数据只由打印字符和控制字符
\t
及\n
组成(尤其是 Windows OS 上,字符'\0x1A'
终止输入) - 没有 \n 立即前附空格符(立即先于 \n 写入的空格符可能在读取时消失)
- 尾字符是 \n
二进制流是能通透地记录内部数据的有序字符序列。从二进制流读取的数据始终与先前写出到该流者比较相等。仅允许实现后附一些空字符到流结尾。宽二进制流不必终止于初始迁移状态。
POSIX 实现不辨别文本与二进制流(无 \n 或任何其他字符的特殊映射)。
函数
定义于头文件 <cstdio>
文件访问 | |
fopen | 打开文件 (函数) |
freopen | 以不同名称打开既存流 (函数) |
fclose | 关闭文件 (函数) |
fflush | 将输出流与实际文件同步 (函数) |
fwide | 在宽字符 I/O 和窄字符 I/O 间切换文件流 (函数) |
setbuf | 为文件流设置缓冲区 (函数) |
setvbuf | 为文件流设置缓冲区与其大小 (函数) |
直接输入/输出 | |
fread | 从文件读取 (函数) |
fwrite | 写入文件 (函数) |
无格式输入/输出 | |
字节/多字节字符 | |
fgetcgetc | 从文件流获取字符 (函数) |
fgets | 从文件流获取字符串 (函数) |
fputcputc | 写字符到文件流 (函数) |
fputs | 写字符串到文件流 (函数) |
getchar | 从 stdin 读取字符 (函数) |
gets (C++11 中弃用)(C++14 中移除) | 从 stdin 读取字符串 (函数) |
putchar | 写字符到 stdout (函数) |
puts | 写字符串到 stdout (函数) |
ungetc | 把字符放回文件流 (函数) |
宽字符 | |
fgetwcgetwc | 从文件流获取宽字符 (函数) |
fgetws | 从文件流获取宽字符串 (函数) |
fputwcputwc | 写宽字符到文件流 (函数) |
fputws | 写宽字符串到文件流 (函数) |
getwchar | 从 stdin 读取宽字符 (函数) |
putwchar | 写宽字符到 stdout (函数) |
ungetwc | 把宽字符放回文件流 (函数) |
有格式输入/输出 | |
字节/多字节字符 | |
scanffscanfsscanf | 从 stdin、文件流或缓冲区读取有格式输入 (函数) |
vscanfvfscanfvsscanf (C++11)(C++11)(C++11) | 使用可变实参列表 从 stdin、文件流或缓冲区读取有格式输入 (函数) |
printffprintfsprintfsnprintf (C++11) | 打印有格式输出到 stdout、文件流或缓冲区 (函数) |
vprintfvfprintfvsprintfvsnprintf (C++11) | 使用可变实参列表 打印有格式输出到 stdout、文件流或缓冲区 (函数) |
宽字符 | |
wscanffwscanfswscanf | 从 stdin、文件流或缓冲区读取有格式宽字符输入 (函数) |
vwscanfvfwscanfvswscanf (C++11)(C++11)(C++11) | 使用可变实参列表 从 stdin、文件流或缓冲区读取有格式宽字符输入 (函数) |
wprintffwprintfswprintf | 打印有格式宽字符输出到 stdout、文件流或缓冲区 (函数) |
vwprintfvfwprintfvswprintf | 使用可变实参列表打印 有格式宽字符输出到 stdout、文件流或缓冲区 (函数) |
文件寻位 | |
ftell | 返回当前文件位置指示器 (函数) |
fgetpos | 获取文件位置指示器 (函数) |
fseek | 移动文件位置指示器到文件中的指定位置 (函数) |
fsetpos | 移动文件位置指示器到文件中的指定位置 (函数) |
rewind | 移动文件位置指示器到文件起始 (函数) |
错误处理 | |
clearerr | 清除错误 (函数) |
feof | 检查文件尾 (函数) |
ferror | 检查文件错误 (函数) |
perror | 显示对应当前错误的字符串于 stderr (函数) |
文件上的操作 | |
remove | 删除文件 (函数) |
rename | 重命名文件 (函数) |
tmpfile | 创建并打开一个临时、自动移除的文件 (函数) |
tmpnam | 返回一个唯一独有的文件名 (函数) |
类型
类型 | 定义 |
FILE | 对象类型,足以保有控制 C I/O 流所需的全部信息 |
fpos_t | 完整非数组对象类型,足以唯一指定文件中的位置,包含其多字节剖析状态 |
size_t | sizeof 运算符返回的无符号整数类型 (typedef) |
宏
stdinstdoutstderr | 与输入流关联到 FILE* 类型表达式 与输出流关联的 FILE* 类型表达式 与错误输出流关联的 FILE* 类型表达式 (宏常量) |
EOF | 拥有 int 类型和负值的整数常量表达式 (宏常量) |
FOPEN_MAX | 能同时打开的文件数 (宏常量) |
FILENAME_MAX | 要保有最长受支持文件名的 char 数组所需的长度 (宏常量) |
BUFSIZ | std::setbuf 所用的缓冲区大小 (宏常量) |
_IOFBF_IOLBF_IONBF | 给 std::setbuf 的参数,指示全缓冲 I/O 给 std::setbuf 的参数,指示行缓冲 I/O 给 std::setbuf 的参数,指示无缓冲 I/O (宏常量) |
SEEK_SETSEEK_CURSEEK_END | 给 std::fseek 的参数,指示从文件起始寻位 给 std::fseek 的参数,指示从当前文件位置寻位 给 std::fseek 的参数,指示从文件尾寻位 (宏常量) |
TMP_MAX | std::tmpnam 所能生成的唯一文件名的最大数量 (宏常量) |
L_tmpnam | 保有 std::tmpnam 结果的 char 数组所需的大小 (宏常量) |