9.1 输入/输出的基本过程和文件类型
9.1.1 输入/输出的基本过程
输入输出是数据传送的过程,数据如流水一样从一处流向另一处,因此常将输人输出形象地称为流(stream),即数据流。流表示了信息从源到目的端的流动。在输人操作时,数据从文件流向计算机内存,在输出操作时,数据从计算机流向文件(如打印机、磁盘文件)。文件是由运行环境(即操作系统)进行统一管理的,无论是用 Word 打开或保存文件,还是 C 程序中的输人输出都是通过操作系统进行的。"流" 是一个传输通道,数据可以从运行环境流入程序中,或从程序流至运行环境。
从 C 程序的观点来看,无论程序一次读写一个字符,或一行文字,或一个指定的数据区,作为输入输出的各种文件或设备都是统一以逻辑数据流的方式出现的。C 语言把文件看作是一个字符(或字节)的序列,即由一个一个字符(或字节)的数据顺序组成。一个输入输出流就是一个字符流或字节(内容为二进制数据)流。
C 的数据文件由一连串的字符(或字节)组成,而不考虑行的界限,两行数据间不会自动加分隔符,对文件的存取是以字符(字节)为单位的。输人输出数据流的开始和结束仅受程序控制而不受物理符号(如回车换行符)控制,这就增加了处理的灵活性。这种文件称为流式文件。
9.1.2 文件类型
-
从用户观点:
-
特殊文件(标准输入输出文件或标准设备文件)。
-
普通文件(磁盘文件)。
-
-
从操作系统的角度看,每一个与主机相连的输入输出设备看作是一个文件。
-
输入文件:终端键盘
-
输出文件:显示屏和打印机
-
-
按数据的组织形式:
-
ASCII文件(文本文件):每一个字节放一个 ASCII 代码
-
二进制文件:把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放。
-
9.2 文件的打开、创建和关闭
9.2.1 文件的打开
- fopen 调用格式:
fopen(文件名,使用文件方式);
- 需要打开的文件名,也就是准备访问的文件的名字;
- 使用文件的方式("读" 还是 "写" 等);
- 让哪一个指针变量指向被打开的文件。
FILE *fp; // 定义一个指向文件的指针变量 fp
fp = fopen("a1", "I"); // 将 fopen 函数的返回值赋给指针变量 fp
文件使用方式:
r
(只读):为输入打开一个文本文件。w
(只写):为输出打开一个文本文件。a
(追加):向文本文件尾增加数据。rb
(只读):为输入打开一个二进制文件。wb
(只写):为输出打开一个二进制文件。ab
(追加):向二进制文件尾增加数据。r+
(读写):为读 / 写打开一个文本文件。w+
(读写):为读 / 写建立一个新的文本文件。a+
(读写):为读 / 写打开一个文本文件。rb+
(读写):为读 / 写打开一个二进制文件。wb+
(读写):为读 / 写建立一个新的二进制文件。ab+
(读写):为读 / 写打开一个二进制文件。
9.2.2 文件的关闭
- fclose 调用格式:
fclose (文件指针);
- fclose 函数功能:使文件指针变量不指向该文件,也就是文件指针变量与文件 "脱钩",此后不能再通过该指针对原来与其相联系的文件进行读写操作。如果关闭成功则函数返回 0;否则函数返回 EOF(-1)。
9.3 文件数据的正文(文本)格式读写
9.3.1 字符输入输出函数
- fgetc 函数:
fgetc(fp)
- 功能:从 fp 指向的文件读入一个字符。读成功,带回所读的字符;失败则返回文件结束标志 EOF(即-1)。
- fputc 函数:
fputc(ch, fp)
- 功能:把字符 ch 写到文件指针变量 fp 所指向的文件中。输出成功,返回值就是输出的字符;输出失败,则返回 EOF(即-1)。
9.3.2 字符串输入输出函数
-
fgets 函数:
fgets(str, n, fp)
- 功能:从 fp 指向的文件读人一个长度为(n-1)的字符串,存放到字符数组 str 中。
读成功,返回地址 str,失败则返回 NULL。
-
fputs 函数:
fputs(str, fp)
- 功能:把 str 所指向的字符串写到文件指针变量 fp 所指向的文件中。
输出成功,返回 0;否则返回非 0 值。
- 功能:把 str 所指向的字符串写到文件指针变量 fp 所指向的文件中。
9.3.3 格式化读写函数
-
fprintf(文件指针, 格式字符串, 输出表列);
-
fscanf(文件指针, 格式字符串, 输入表列);
-
函数功能:从磁盘文件中读入或输出字符。
注意:
用 fprintf 和 fscanf 函数对磁盘文件读写,使用方便,容易理解,但由于在输入时要将ASCII码转换为二进制形式,在输出时又要将二进制形式转换成字符,花费时间比较多。因此,在内存与磁盘频繁交换数据的情况下,最好不用 fprintf 和 fscanf 函数,而用 fread 和 fwrite 函数。
9.3.5 其他读写函数
-
putw()
和getw()
-
函数调用:
putw(int i, FILE *fp);
、inti = getw(FILE *fp);
-
函数功能:对磁盘文件中读写一个字(整数)。
-
例如:
putw(10, fp);
、i = getw(fp);
9.4 读写操作中的定位
9.4.1 rewind 函数
- 函数调用:
rewind(fp1);
- 函数作用:使位置指针重新返回文件的开头,无返回值。
9.4.2 fseek 函数
- 函数调用:
fseek(文件类型指针, 位移量, 起始点)
- 函数功能:改变文件的位置指针。
- 函数参数:
- 起始点:
- 文件开头 SEEK_SET 0
- 文件当前位置 SEEK_CUR 1
- 文件末尾 SEEK_END 2
- 位移量:以起始点为基点,向前移动的字节数。一般要求为 long 型。
- 应用举例:
fseek(fp, 100L, 0);
:将位置指针移到离文件头 100 个字节处。fseek(fp, 50L, 1);
:将位置指针移到离当前位置 50 个字节处。fseek(fp, 50L, 2);
:将位置指针从文件末尾处向后退 10 个字节。
9.4.3 ftell 函数
-
函数调用:
i = ftell(fp);
-
函数功能:得到流式文件中的当前位置,用相对于文件开头的位移量来表示。函数返回值为当前位置,出错时返回 -1L。
-
应用举例:
i = ftell(fp); if(i == -1L) printf(“error\n”);
9.4.4 ferror 函数
- 函数调用:
ferror(fp);
- 函数功能:返回0,表示未出错;返回非0,表示出错。
9.4.5 clearerr 函数
- 函数调用:
clearerr(fp);
- 函数功能:使文件错误标志和文件结束标志置为 0。只要出现错误标志,就一直保留,直到对同一文件调用 clearerr 函数或 rewind 函数,或任何其他一个输入输出函数。
9.5 文件数据的二进制格式读写
9.5.1 数据块读写函数
fread(buffer, size, count, fp);
fwrite(buffer, size, count, fp);
- 参数说明:
buffer
:是一个指针。对 fread 来说,它是读入数据的存放地址。对 fwrite 来说,是要输出数据的地址(均指起始地址)。size
:要读写的字节数。count
:要进行读写多少个 size 字节的数据项。fp
:文件型指针。
例如:
fread(f,4,2,fp); // 此函数从 fp 所指向的文件中读入 2 个 4 个字节的数据,存储到数组f中。
若有如下结构类型:
struct student_type
{
char name[10];
int num;
int age;
char addr[30];
} stud[40];
可以用 fread 和 fwrite 来进行数据的操作:
for (int i = 0; i < 40; i++) {
fread(&stud[i], sizeof(struct student_type), 1, fp);
}
for (int i = 0; i < 40; i++) {
fwrite(&stud[i], sizeof(struct student_type), 1, fp);
}
9.6 文件输入输出总结
分类 | 函数名 | 功能 |
打开文件 | fopen() | 打开文件 |
关闭文件 | fclose() | 关闭文件 |
文件定位 | fseek() | 改变文件位置指针的位置 |
rewind() | 使文件位置指针重新至于文件开头 | |
ftell() | 返回文件位置指针的当前值 | |
文件状态 | feof() | 若到文件末尾,函数值为真 |
ferror() | 若对文件操作出错,函数值为真 | |
Clearerr() | 使 ferror 和 feof() 函数值置零 | |
文件读写 | fgetc(),getc() | 从指定文件取得一个字符 |
fputc(),putc() | 把字符输出到指定文件 | |
fgets() | 从指定文件读取字符串 | |
fputs() | 把字符串输出到指定文件 | |
getw() | 从指定文件读取一个字(int 型) | |
putw() | 把一个字输出到指定文件 | |
fread() | 从指定文件中读取数据项 | |
fwrite() | 把数据项写到指定文件中 | |
fscanf() | 从指定文件按格式输入数据 | |
fprintf() | 按指定格式将数据写到指定文件中 |
评论(没有评论)