C语言 文件输入输出
本文将介绍在 C 语言中如何创建、打开、关闭文本文件或二进制文件。
一、文件的基本知识
1.什么是文件
(1) 程序文件和数据文件
文件有不同的类型,在程序设计中,主要用到两种文件:
- 程序文件:存储程序代码
- 数据文件:文件的内容是供程序运行时读写的数据。
本文主要讨论的是数据文件。
(2) 数据的文件存储
文件是程序设计中的一个重要概念,指存储在外部介质上数据的集合。数据以文件的形式存放在外部介质中,操作系统以文件为单位对数据进行管理。
(3) C 中的文件
C 语言把文件看作一个字符(或字节)的序列,即由一个个字符(或字节)的数据顺序组成。一个输入输出流就是一个字符流或字节流(内容为二进制数据)。 C 的数据文件由一连串的字符(或字节)组成,不考虑行的界限,增加了处理的灵活性。这种文件被称为流式文件。
2.文件名
一个文件要有一个唯一的文件标识,以便用户识别和引用。文件标识包括 3 部分:
- 文件路径:在哪里找
- 文件名:叫什么名字
- 文件后缀:怎么处理
3.文件的编码形式
根据文件存储的编码形式,数据文件可分为文本文件和二进制文件。
文本文件是以字符 ASCII 码值进行存储和编码的文件,其文件内容就是字符, 需要在存储前进行转换,又称为文本文件;
二进制文件直接将内存中的数据不加转换地输出到外存,可以将外存中的数据看作内存的映像,又称为映像文件。
如何选择?
- 文本的优势在于方便人类读写,并且跨平台
- 文本的缺点是程序输入输出时需要进行转换
- 二进制的缺点是人类读写困难,且不支持跨平台
- 二进制的优点是程序输入输出时速度更快
4.文件缓冲区
ANSI C 标准采用缓冲文件系统处理数据文件。系统会自动地为每一个文件分配一个文件缓冲区。写入数据时,先将数据存到缓冲区,再由操作系统把缓冲区数据真正存入磁盘。读入数据时,先将数据写入缓冲区,再由缓冲区读入到内存。这样做节省了存取时间,提高了效率。
每个文件在内存中只有一个缓冲区,它在输入时作为输入缓冲区,输出时作为输出缓冲区。
5.文件类型指针
在 C 语言中,每一个被使用的文件都在内存中开辟一个相应的文件信息区,用来存放文件的有关信息。这些信息存在 FILE 这个结构体变量中,它由系统声明,并且不同 C 编译系统中的 FILE 类型都有所不同。
通常,不定义 FILE 类型的变量,而是定义一个 FILE 类型的指针,指向内存中文件信息区的开头,通过它来引用变量。
1 |
|
二、打开和关闭文件
1.打开和关闭
在 C 语言中的打开文件,是指为文件建立相应的信息区(用来存放有关文件的信息)和文件缓冲区(用来缓冲输入输出的数据)。在打开文件的同时,一般都指定一个指针变量指向该文件,建立起指针变量和文件之间的联系,方便之后的读写操作。
在 C 语言中的关闭文件,是指撤销文件信息区和文件缓冲区。
2.fopen
(1) 调用形式
1 |
|
此处加双引号是在它是字符串常量的情况下,
如果由字符串变量存储文件名和打开方式,则无需加引号。
(2) 标准代码
打开文件,用指针接受地址信息,并判断打开是否成功。
1 |
|
或
1 |
|
(3) 文件名
文件名应该包含文件路径、文件名、文件后缀三部分
文件路径:若数据文件在程序文件目录下,则可以不用指定文件路径,否则需要指定。
例如:
D:/Documents/test.txt
或
D:\\Documents\\test.txt
(4) 使用文件方式
在第一个字母后面加 b ,便可以使用二进制方式使用文件。而实际上文本方式和二进制方式的区别仅在于对”换行”的处理。C语言中,”换行”为 ‘\n’ ,而 Windows 中, “换行”为 ‘\r’和’\n’ ,因此需要进行转换。
(5) 标准流文件
程序中可以使用 3 个标准的流文件:标准输入流(stdin)、标准输出流(stdout)、标准出错输出流(stderr)。
3.fclose
(1) 调用形式
1 |
|
(2) 必须关闭
- 在使用完文件后应该关闭它,防止误用
- 如果不关闭文件就结束程序运行将会丢失数据
三、顺序读写数据文件
1.读写字符
(1) 调用形式
1 |
|
在 C 语言中, fgetc 等价于 getc , fputc 等价于 putc
(2) 例 1
从键盘输入一些字符,并逐个将他们写入到文件,知道用户输入一个 ‘#’ 为止。
1 |
|
(3) 例 2
将一个磁盘文件中的信息复制到另一个文件中。
1 |
|
- 在文件的所有有效字符后有一个文件尾标志,用标识符 EOF 表示,其值为 -1
ch != EOF
等价于ch != -1
等价于!feof(in)
2.读写字符串
1 |
|
若字符数组大小为 n ,此时应填入 n ,字符串大小最大为 n - 1
3.格式化方式读写
1 |
|
用 fprintf 和 fscanf 函数对文件读写,
优点:使用方便,容易理解,支持跨平台
缺点:由于输入输出时都需要进行二进制与 ASCII 码之间的转换,需要花费额外的时间。
4.二进制方式读写
在程序中不仅需要一次输入输出一个数据,而且往往需要一次输入输出一组数据, C 语言允许用 fread 从文件中读一个数据块,用 fwrite 向文件写一个数据块。读和写都是以二进制进行,数据在内存和文件之间原封不动地转移。
(1) 调用形式
1 |
|
对于 fread 来说,地址是指用来存放读入数据的储存区的地址;
对于 fwrite 来说,地址是指要将这个地址开始的存储区中的数据写入文件。
若函数执行成功,则返回数据项的个数
例如:
1
2
int f[10];
fread(f, sizeof(int), 10, fp);从 fp 所指的文件中读入 10 个 sizeof(int) 字节的数据,存储到数组 f 中。
(2) 例 1
从键盘输入 10 个学生的有关数据,然后把它们转存到文件中。
1 |
|
(3) 例 2
从文件中读入数据,并将其打印在屏幕上.
1 |
|
四、随机读写数据文件
1.文件位置标记
系统为每个文件设置了一个文件读写位置标记,用来指示“接下来要读写的下一个字符的位置”。
2.rewind
(1) 函数作用
rewind 函数的作用是使文件位置标记重新范围文件的开头,于是便可以从头开始处理文件。
(2) 调用形式
1 |
|
(3) 示例
读一个文件两次,第一次将其中数据现实在屏幕上,第二次将它复制到另一文件中。
1 |
|
3.fseek
(1) 函数作用
跳转到文件中的指定位置。
(2) 调用形式
1 |
|
(3) 位移量
位移量是指以起始点为基点,位移的字节数,有正负之分。位移量应是 long 型,需要在数字后加 l 。
(4) 起始点
位移的基点,用数字表示。其中, 0 表示文件开始位置; 1 表示当前位置; 2 表示文件末尾位置。
(5) 示例
1 |
|
4.ftell
(1) 函数作用
得到文件中”文件位置标记”的当前位置。如果出错,将会返回 -1L 。
(2) 调用形式
1 |
|
五、文件读写的出错检测
1.ferror
(1) 函数作用
用于检查是否发生错误,返回值为 0 表示未出错,返回值非 0 表示出错。
(2) 调用形式
1 |
|
2.clearerr
(1) 函数作用
将文件出错标志和文件结束标志置为 0 。
(2) 调用形式
1 |
|
参考
- C程序设计
- C Primer Plus
- C 语言教程 | 菜鸟教程