C/文件输入输出
C语言提供了许多用于文件输入输出的标准库函数. 这些函数构成了C标准库的头文件 <stdio.h>
.
以现代的标准来看, C语言的 I/O 功能相当的低级; C 将对所有文件比特流(可以为输入流或输出流)的操作进行抽象. 不像其他更早的程序语言, C语言不支持数据文件的随机存取; 如果想要读取一个文件中间的记录, 程序员必须创建一个流, 找到文件的中间部分, 然后读取流中的比特序列.
文件 I/O 的流模型在Unix操作系统中应用广泛. 现代的许多主流操作系统都从 Unix 继承了流的概念, 许多类C语言继承了C的文件I/O接口或仅在其基础上做了少许改动(例如, PHP).C++标准库在其语法中反映了"流"的概念; 查看iostream.
使用fopen打开文件
[编辑]使用 fopen
打开文件将返回一个相应文件或其他设备的输入/输出流. 如果函数调用失败, 将返回一个空指针.
The related C library function freopen
performs the same operation after first closing any open stream associated with its parameters.
他们的定义如下:
FILE *fopen(const char *path, const char *mode);
FILE *freopen(const char *path, const char *mode, FILE *fp);
fopen
和 freopen
的模式 mode
参数必须是下面序列中的 字符串:
模式 | 描述 | 起始位置 | ||
---|---|---|---|---|
r | rb | 用于读取 | 文件起点 | |
w | wb | 用于写入 ( 如果文件不存在则创建文件). 删除文件内容并重新写入. | 文件起点 | |
a | ab | 用于增量写入 (如果文件不存在则创建文件) | 文件末尾 | |
r+ | rb+ | r+b | 用于读写 | 文件起点 |
w+ | wb+ | w+b | 用于读写. 删除文件内容并重新写入. | 文件起点 |
a+ | ab+ | a+b | 用于读写 (如果文件存在则增量写入) | 文件末尾 |
字母 "b" 代表二进制. 标准 C 提供两类文件: 文本文件 和 二进制文件 , 虽然操作系统不需要区分这两种形式.
使用 fclose 关闭流
[编辑]fclose
函数只有一个参数: 指向需要关闭流的 FILE
结构的指针, 即
int fclose(FILE *fp);
使用 fgetc 从流中读入
[编辑]fgetc
函数用于从一个流中读取字符.
int fgetc(FILE *fp);
如果调用成功, fgetc
返回流中的下一位或下一字符(取决于文件是"二进制文件"或"文本文件"). 如果不成功, fgetc 返回 EOF
.
标准宏 getc
除了作为宏可能会对其参数求值两次之外与 fgetc
的行为几乎完全一样.
标准函数 getchar
不需要任何参数, 等价于 getc(stdin)
.
函数 fgetc
, getc
, getchar
都在头文件 <stdio.h>
中定义.
EOF 陷阱
[编辑]使用 fgetc
, getc
, 或 getchar
的常见的一个错误是, 在不将返回值与 EOF
比较的情况下, 用返回值为 char
型变量赋值. 下面的代码片段示例了这种错误, 并且示例了正确的方法:
错误 | 正确 |
---|---|
char c;
while ((c = getchar()) != EOF) {
putchar(c);
}
|
int c;
while ((c = getchar()) != EOF) {
putchar(c);
}
|
考虑一个 char
型是 8 比特的系统, char
可以表示 256 个不同的值. getchar
可以返回 256 个可能字符串的任何一个, 并且它可能返回 EOF
来代表文件的结束, 这样有 257 个可能的返回值.
当用 getchar
的返回值给 char
型变量赋值时, 这一变量仅能表示 256 个不同的值, 这将造成信息丢失.
查阅
[编辑]参考文献
[编辑]外部链接
[编辑]- Question 12.1 in the C FAQ: using
char
to holdgetc
's return value - Source code