1
C 语言程序设计北京科技大学 计算机系第 10章 文 件
2009-7-26
2第 10章 文件
10.1 文件的概念
10.2 文本文件的读写
10.3 二进制文件的读写
2009-7-26
3
文件,存储在 外部存储介质 上相关 数据 的集合 。
例如:程序文件中保存着程序,数据文件中保存着数据 。
*.C C语言的源程序 文本文件
*.OBJ 目标文件 二进制文件
*.EXE 可执行文件 二进制文件
文件的存储特性文件是一个 有序的数据序列 。 C语言把文件作为 一个字符 ( 字节 ) 序列 处理,对文件的存取是以字符 ( 字节 ) 为单位进行的 。
10.1 文件的概述
10.1.1 文件和文件指针
1,什么是文件
2009-7-26
4
设备文件在 C语言中,,文件,的概念被进一步扩大,
把每台与主机相连的 输入输出设备 都看作是一个文件 。 即把实际的物理设备抽象为逻辑文件,它们被称为 设备文件 。
对外部设备的输入输出就是对设备文件的读写 。
10.1 文件的概述
10.1.1 文件和文件指针
1,什么是文件
2009-7-26
5
按文件存储数据的形式
ASCII文件 ( 或称 文本文件 )
ASCII码文件中 每个字节 存放一个 ASCII代码,代表一个字符,此种存储形式便于输出显示,在 DOS操作系统下可以直接阅读 。
二进制文件二进制文件 中的 数据 是按照在内存中的 二进制 存储格式 存放的,此种存储形式节省存储单元 。 二进制文件在 DOS操作系统下不能直接阅读 。
10.1 文件的概述
10.1.1 文件和文件指针
2,文件的种类
2009-7-26
6
例如将整数 1949分别存储在这两种数据文件中 。
ASCII文件,ASCII码二进制文件:补码占用 4个字节占用 2个字节
10.1 文件的概述
10.1.1 文件和文件指针
2,文件的种类
00110001 00111001 00110100 00111001
'1' '9' '4' '9'
00000111 10011101
2009-7-26
7
按照对文件的处理方式
缓冲文件利用缓冲文件系统处理的文件称为缓冲文件 。 系统处理方法是在内存中 为每个正在使用的缓冲文件开辟一个缓冲区,其大小是 512个字节 。 对文件读写数据都通过缓冲区进行 。
非缓冲文件利用非缓冲文件系统处理的文件称为非缓冲文件 。
系统处理非缓冲文件时,不为文件开辟缓冲区,需要程序员自行设计并管理缓冲区 。
83年以后 ANSI C标准中取消了非缓冲文件系统,对文本文件和二进制文件均采用缓冲文件系统进行处理。
10.1 文件的概述
10.1.1 文件和文件指针
2,文件的种类
2009-7-26
8
系统对文件的处理过程就是对文件进行 输入 /输出 操作的过程 。
从文件 读 数据时,先一次性从磁盘文件中读取一批数据到缓冲区,然后再从缓冲区逐个将数据送入变量 。
向文件 写 数据时,也是先将变量中数据送到缓冲区,待缓冲区装满后,再一起存到磁盘文件中 。
10.1 文件的概述
10.1.1 文件和文件指针
3,缓冲文件和文件指针磁盘文件输出输入图 10.2 系统对缓冲文件的处理输入 输出程序区数据区文件缓冲区外存内存
2009-7-26
910.1 文件的概述
10.1.1 文件和文件指针
3,缓冲文件和文件指针
文件类型指针在 缓冲文件系统 中,对每个正在使用的文件都自动分配一个 FILE类型的 结构体变量,用于存放文件的有关信息,如文件号,文件状态,
缓冲区地址和大小等 。
FILE类型是系统定义的,包含在 stdio.h头文件 中在 C语言中,无论对 磁盘文件 还是 设备文件的 读 /写 都要通过 FILE类型的 结构体变量 进行 。
因此 对于每个使用中的磁盘文件 必须 先 定义 一个 FILE类型的 文件指针变量 并指向 此变量 。
FILE *文件指针变量名 ;
typedef struct {
short level; /* fill/empty level of buffer */
unsigned flags; /* File status flags */
char fd; /* File descriptor */
unsigned char hold; /* Ungetc char if no buffer */
short bsize; /* Buffer size */
unsigned char *buffer; /* Data transfer buffer */
unsigned char *curp; /* Current active pointer */
unsigned istemp; /* Temporary file indicator */
short token; /* Used for validity checking */
} FILE; /* This is the FILE object */
2009-7-26
10
标准文件 是外部设备中的三个特殊的设备文件 。 它们的文件指针是系统定义的,并由系统 自动打开和关闭 。 这三个标准文件分别是:
① 标准输入文件,文件指针为 stdin,系统指定为键盘 。
② 标准输出文件,文件指针为 stdout,系统指定为显示器 。
③ 标准错误输出文件,文件指针为 stderr,系统指定为 显示器,输出错误信息 。
10.1 文件的概述
10.1.1 文件和文件指针
4,标准文件
2009-7-26
1110.1 文件的概述
10.1.2 文件的打开与关闭
操作文件的一般步骤打开文件? 读写文件? 关闭文件打开文件,建立 用户程序与文件的 联系,为文件 分配 一个文件缓冲区。
读写文件,是指对文件的 读,写,追加 和 定位 操作。
关闭文件,切断 文件与程序的 联系,释放 文件缓冲区。
C语言的输入输出函数库中提供了大量的函数,用于完成对数据文件的建立、
数据的读写、数据的追加等操作。
在程序中 调用 这些 函数 时,必须先用
include命令包含 stdio.h文件。
2009-7-26
12
常用的 调用 形式:
FILE *fp;
fp = fopen(文件名,文件使用方式 );
文件名,需要打开的文件名称 (字符串 )。
文件使用方式,是具有特定含义的 符号 。
10.1 文件的概述
10.1.2 文件的打开与关闭
1,文件打开函数 fopen()
函数功能:
按指定的 文件使用方式 打开指定的 文件 。
若文件打开 成功,为该文件分配一个文件缓冲区和一个
FILE类型变量,返回一个 FILE类型 指针 ;
若文件打开 失败,返回 NULL。
2009-7-26
13
文本文件的三种基本使用方式
” r”,只读方式为读 (输入 )文本文件打开文件 。 若文件不存在,
返回 NULL。
”w”,只写方式为写 (输出 )文本文件打开文件 。 若文件不存在,
则建立一个新文件;若 文件已存在,则 清空文件 。
” a”,追加方式为写 (输出 )文本文件打开文件 。 若 文件已存在,
则 保持 原来文件的 内容,将新的数据 增加 到原来数据的 后面 ;若文件不存在,则返回 NULL。
10.1 文件的概述
10.1.2 文件的打开与关闭
2009-7-26
14
二进制文件的三种基本使用方式
” rb”,只读方式为读 (输入 )二进制文件打开文件 。 若文件不存在,
返回 NULL。
”wb”,只写方式为写 (输出 )二进制文件打开文件 。 若文件不存在,
则建立一个新文件;若 文件已存在,则 清空文件 。
” ab”,追加方式为写 (输出 )二进制文件打开文件 。 若 文件已存在,
则 保持 原来文件的 内容,将新的数据 增加 到原来数据的后面 ;若文件不存在,则返回 NULL。
10.1 文件的概述
10.1.2 文件的打开与关闭
2009-7-26
1510.1 文件的概述
10.1.2 文件的打开与关闭
文件的其他打开方式
” r+”,可以对 文本文件 进行 读 /写 操作。
若文件不存在返回 NULL;
若文件存在 内容不 被 清空 。
” w+”,可以对 文本文件 进行 读 /写 操作。
若文件已经存在,则先 清空 文件原来的 内容 。
” a+”,可以对 文本文件 进行 读 /追加 操作。
文件内容不会清空。
” rb+”,可以对 二进制文件 进行 读 /写 操作。
” wb+”,可以对 二进制文件 进行 读 /写 操作。
” ab+”,可以对 二进制文件 进行 读 /追加 操作。
2009-7-26
16
检查文件打开操作是否成功
if((fp = fopen("filename","r")) == NULL)
{ printf (”Cannot open file.\n”);
exit(0);
}
检查以 只读 方式打开文件名为 filename的文件是否成功 。
exit函数的作用,结束程序的执行,并将实参 0作为函数返回值传给操作系统。
10.1 文件的概述
10.1.2 文件的打开与关闭
2009-7-26
17
常用的 调用 形式:
FILE *fp;
fclose( fp );
fp:已经打开的文件指针 。
10.1 文件的概述
10.1.2 文件的打开与关闭
2,文件关闭函数 fclose()
函数功能:
关闭 fp指定的文件,释放该文件的缓冲区、
FILE类型变量及文件指针。
若文件关闭成功,则返回 0;
若文件关闭失败,则返回 非 0值 。
2009-7-26
18
常用的 调用 形式:
FILE *fp;
fputc( ch,fp );
ch,需要输出的字符,可以是字符常量或字符变量;
fp:文件指针变量 。
对文本文件的读写操作,必须 按 文件中字符的 先后顺序 进行,只能在操作了第 i个字符之后,才能操作第 i+1个字符 。
在对文件操作时,文件的 读写指针 由系统 自动向后 移动 。
10.2 文本文件的读写
10.2.1 文件的字符输入输出函数
1,字符输出函数 fputc()( 或 putc())
函数功能:
将一个字符( ASCII码)写入到 fp所指向的文件(该文件必须是以写或读写方式打开的)中。
若输出操作成功,函数返回写入的字符;否则,返回 EOF。
系统定义的文本文件结束标志,其值为 (-1)。
① putc函数与 fputc函数的功能相同 。 在 stdio.h文件中被定义为
#define putc(c,f) fputc((c),f)
② 标准文件中用的 putchar函数是 fputc函数的特殊用法,它在 stdio.h文件中被定义为
#define putchar(c) putc((c),stdout)
2009-7-26
19
常用的 调用 形式:
FILE *fp;
ch = fgetc(fp);
ch,可以是字符变量或整型变量;
fp:文件指针变量 。
10.2 文本文件的读写
10.2.1 文件的字符输入输出函数
2,字符输入函数 fgetc()( 或 getc())
函数功能:
从 fp所指向的文件(该文件必须是以读或读写方式打开的)中读取一个字符。
若输入操作成功,函数返回读入的字符;
若文件结束或输入操作失败,则返回 EOF。
① getc函数与 fgetc函数的功能相同 。 在 stdio.h文件中被定义为
#define getc(f) fgetc(f)
② 标准文件中用的 getchar函数是 fgetc函数的特殊用法,它在 stdio.h文件中被定义为
#define getchar( ) getc(stdin)
2009-7-26
20
【 例 10.1】 利用 fputc和 fgetc函数建立一个文本文件,并显示文件中的内容 。
#include <stdio.h>
main( )
{ FILE *fp; /* 定义一个文件指针变量 fp */
int c; /* c为存放字符的变量 */
char filename[40]; /* filename用于存放数据文件名 */
printf("filename,"); /* 提示输入磁盘文件名 */
gets(filename);
if ((fp=fopen(filename,"w"))==NULL)
{ printf("Can't open the %s\n",filename);
exit(0); }
10.2 文本文件的读写
10.2.1 文件的字符输入输出函数测试打开文件是否成功
2009-7-26
21
while ((c=getchar( ))!=EOF)
/*键盘文件结束标志:输入 Ctrl+z,显示 ^Z后回车 */
putc(c,fp); /* 将键盘输入的字符写到文件中 */
fclose(fp); /* 建立文件结束,关闭文件 */
printf("outfile:\n");
fp=fopen(filename,"r"); /* 以读方式打开文本文件 */
while ((c=getc(fp))!=EOF) /* 未读到文件结束标志时 */
putchar(c); /* 在显示器显示读出的字符 */
fclose(fp); /* 读文件结束,关闭文件 */
}
10.2 文本文件的读写
10.2.1 文件的字符输入输出函数
2009-7-26
22
常用的 调用 形式:
FILE *fp;
feof(fp);
fp:文件指针变量 。
10.2 文本文件的读写
10.2.2 文件结束测试函数函数功能:
测试 fp所指向的文件是否已读到文件尾部。
若该文件没有结束,则返回 0;
若文件结束,则返回 非 0值。
对文本文件进行读操作时,例如 fgetc( )返回
EOF,即可作文件结束处理 。 但在二进制文件中 -1
是 合法数据,所以系统提供了一个适用对象更普遍的文件结束测试函数 feof。
2009-7-26
23
例如,复制一个磁盘文件 。
#include <stdio.h>
main()
{ FILE *infp,*outfp; char infile[40],outfile[40];
int ch;
printf("input filename:"); scanf("%s",infile);
printf("output filename:"); scanf("%s",outfile);
if((infp=fopen(infile,"r"))==NULL) /* 打开源文件 */
{ printf("infile open error.\n"); exit(0);}
if((outfp=fopen(outfile,"w"))==NULL)/* 打开目标文件 */
{ printf("outfile open error.\n"); exit(0);}
ch=fgetc(infp); /* 从 源 文件中读一个字符 */
while(!feof(infp)) /* 源 文件未读完 */
{ fputc(ch,outfp); ch=fgetc(infp); }/* 复制文件 */
fclose(infp); fclose(outfp);
}
10.2 文本文件的读写
10.2.2 文件结束测试函数
2009-7-26
24
常用的 调用 形式:
FILE *fp;
fputs(str,fp);
str,需要输出的字符串,可以是字符串常量或字符串指针;
fp:文件指针变量 。
fputs与 puts函数的功能类似,它们的区别:
puts函数能将字符串的结束标志 '\0' 转换成
'\n' 输出,因此字符串在显示器输出后,光标移至下一行;而 fputs函数对字符串结束标志 '\0' 的处理仅仅是将其 舍去 。
10.2 文本文件的读写
10.2.3 文件的字符串输入输出函数
1,字符串输出函数 fputs()
函数功能:
将字符串 ( 不包括字符串结束标志 '\0') 写到文件指针
fp所指向的文件中 。
若输出操作成功,返回 非 0值 ;
若输出操作失败,则返回 0。
2009-7-26
25
常用的 调用 形式:
FILE *fp;
fgets(str,n,fp);
str,字符指针,可以是字符数组名或字符指针变量 ;
n,读取字符个数( n-1)。
fp:文件指针变量 。
10.2 文本文件的读写
10.2.3 文件的字符串输入输出函数
2,字符串输入函数 fgets()
函数功能:
从 fp所指向的文件中,读取 n-1个字符后,加上字符串结束标志 '\0'组成一个字符串,存入字符数组中。
若输入操作成功,返回字符数组的首地址;
若文件结束或输入操作失败,则返回 NULL。
① 从文件读取字符的过程中,如果读到 回车符 ( '\15')
舍去,如果读到 换行符 ( '\12') 仍按字符 读出,再 加上 '\0'
作为一个字符串,同时 结束 文本行 读取操作,函数正常返回 。 当 读到文件结束 时,直接 加上 '\0'作为一个字符串,函数正常返回 。
② fgets与 gets函数的区别,gets函数 以换行符 作为行 结束标志,并 舍去 换行符 。 fgets函数也以换行符作为行的读结束标志,但 换行符 同时还 作为字符串的内容 。 因此可将含有换行符的文本文件看作是由一行一行字符组成的 。
2009-7-26
26
【 例 10.3】 应用 fputs和 fgets函数,建立和读取文本文件 。
#include "stdio.h"
#include "string.h"
main( )
{ FILE *fp; /* 定义一个文件指针变量 fp*/
char filename[40],str[81];
printf("filename,"); /* 提示输入磁盘文件名 */
gets(filename);
if ((fp=fopen(filename,"w"))==NULL)
/* 在磁盘中新建并打开一个文本文件,同时测试是否成功 */
{ printf("Can' t open the %s\n",filename);
exit(0);
}
10.2 文本文件的读写
10.2.3 文件的字符串输入输出函数
2009-7-26
27
while (strlen(gets(str))>0)
/* 键盘输入空串 ( 即仅输入回车 ) 则输入全部结束 */
{ fputs(str,fp); /* 将键盘输入的字符串写到文件中 */
fputc('\n',fp); /* 在文件中加入换行符作为字符串分隔符 */
}
fclose(fp); /* 建立文件结束,关闭文件 */
printf("outfile:\n");
fp=fopen(filename,"r"); /* 以读方式打开文本文件 */
while ((fgets(str,81,fp))!=NULL)
/* 从文件读取字符串并测试文件是否已读完 */
printf("%s",str); /* 将文件中读取的字符串分行显示 */
fclose(fp); /* 读文件结束,关闭文件 */
}
10.2 文本文件的读写
10.2.3 文件的字符串输入输出函数
2009-7-26
28
与标准文件的格式输入输出函数 scanf和 printf相对应,文本文件也有格式输入输出函数 fscanf和
fprintf。 它们的功能和格式基本相同,不同之处在于 scanf和 printf的读写对象是终端 ( 键盘和显示器 ),fscanf和 fprintf的读写对象是磁盘文件 。
常用的 调用 形式:
FILE *fp;
fprintf(fp,格式控制串,输出项参数表 );
fp:文件指针变量 。
格式控制串 和 输出项参数表 的规定和使用方法与
printf函数相同 。
10.2 文本文件的读写
10.2.4 文件的格式输入输出函数
1,格式输出函数 fprintf()
函数功能:
将输出项按指定格式写入 fp所指向的文件中 。
若输出操作成功,返回 写入的字节数 ;
若输出操作失败,则返回 EOF。
2009-7-26
29
常用的 调用 形式:
FILE *fp;
fscanf(fp,格式控制串,地址 表 );
fp:文件指针变量 。
格式控制串 和 地址表 的规定和使用方法与 scanf函数相同 。
10.2 文本文件的读写
10.2.4 文件的格式输入输出函数
2,格式输入函数 fscanf()
函数功能:
按格式控制串所描述的格式,从 fp所指向的文件中读取数据,送到指定的内存地址单元中 。
若输入操作成功,返回实际读出的数据项个数,不包括数据分隔符 。 若没有读数据项,则返回 0。
若文件结束或调用失败,则返回 EOF。
2009-7-26
30
二进制文件 存储信息的形式与 内存 中存储信息的形式是一致的,如果需要在内存与磁盘文件之间频繁交换数据,最好采用二进制文件 。
二进制文件一般是 同类型数据 集合,数据之间无分隔符,每个数据所占字节数是一个定值,因此二进制文件除了可以顺序存取外,还可运用定位函数方便地进行随机存取 。
常用的 调用 形式:
FILE *fp;
putw(w,fp);
w,要输出的整型数据,可以是常量或变量 。
fp:文件指针变量 。
10.3 二进制文件的读写
10.3.1 文件的字输入输出函数
1,字输出函数 putw()
函数功能:
把整型数 w写入 fp所指向的文件( 以写方式打开的二进制文件 )。
若输出操作成功,返回 w值 ;
若输出操作失败,则返回 EOF。
由于 EOF(-1)是一个合法的整数,因此应该用 ferror函数检测函数调用是否出错。
2009-7-26
31
常用的 调用 形式:
FILE *fp;
getw(fp);
fp:文件指针变量 。
10.3 二进制文件的读写
10.3.1 文件的字输入输出函数
2,字输入函数 getw()
函数功能:
从 fp所指向的文件 ( 以读方式打开的二进制文件 )
中读取一个整型数 。
若输入操作成功,返回从文件中读取的整数 。
若文件结束或调用失败,则返回 EOF。
EOF(-1)是 getw函数可能返回的合法值,所以应该用 feof
函数或 ferror函数检测文件是否结束或调用失败。
2009-7-26
32
常用的 调用 形式:
FILE *fp;
ferror(fp);
fp:文件指针变量 。
10.3 二进制文件的读写
10.3.1 文件的字输入输出函数
3,文件操作错误函数 ferror()
函数功能:
检测文件读写是否出错 。
若出错,则指示器 置 1,否则指示器 置 0。
函数返回错误指示器值 。
说明,错误指示器若 置 1后,只有调用 clearerr函数或
rewind函数才能将其 清 0。
2009-7-26
33
常用的 调用 形式:
FILE *fp;
clearerr(fp);
fp:文件指针变量 。
10.3 二进制文件的读写
10.3.1 文件的字输入输出函数
4,清除错误标志函数 clearerr()
函数功能:
将文件的错误指示器和文件结束指示器 清 0。
该函数无返回值 。
2009-7-26
34
【例 10.5】应用 putw和 getw函数建立二进制整型数据文件并读取其中的数据。
#include "stdio.h"
main( )
{ FILE *fp; /* 定义一个文件指针变量 fp*/
char filename[40]; /* filename用于存放数据文件名 */
int i,n1=5,n2,x[5]={10,22,36,48,59},y[5];
printf("filename,");
gets(filename);
if ((fp=fopen(filename,"wb"))==NULL)
/* 新建并打开一个二进制文件,并测试是否成功 */
{ printf("Can' t open the %s\n",filename);
exit(0);
}
10.3 二进制文件的读写
10.3.1 文件的字输入输出函数
2009-7-26
35
putw(n1,fp); /* 向二进制文件写入一个整数 */
for (i=0; i<n1; i++)
putw(x[i],fp); /* 将 x数组的 5个整数写入二进制文件 */
fclose(fp); /* 建立文件结束,关闭文件 */
printf("outfile:\n");
fp=fopen(filename,"rb"); /* 以读方式打开二进制文件 */
n2=getw(fp); /* 从二进制文件读取一个整数 */
for (i=0; i<n2; i++)
{ y[i]=getw(fp); /* 从文件读取一个整数赋给 y数组元素 */
printf("%d ",y[i]);
}
printf("\n");
fclose(fp); /* 读文件结束,关闭文件 */
}
10.3 二进制文件的读写
10.3.1 文件的字输入输出函数
2009-7-26
36
常用的 调用 形式:
fwrite(p,size,n,fp);
p,某类型指针;
size,某类型数据存储空间的字节数(数据项大小);
n,此次写入文件的数据项数;
fp:文件指针变量 。
10.3 二进制文件的读写
10.3.2 文件的数据块输入输出函数
1,数据块输出函数 fwrite()
函数功能:
将 p指向的存储区中 n个数据项写入 fp所指向的文件 。
若输出操作成功,返回 写入的数据项数 ;
若输出操作失败,则返回 0。
运用数据块输入输出函数可建立整型、实型、结构体类型等各种类型的二进制文件。
2009-7-26
37
常用的 调用 形式:
fread(p,size,n,fp);
p,某类型指针;
size,某类型数据存储空间的字节数(数据项大小);
n,此次从文件中读取的数据项数;
fp:文件指针变量 。
10.3 二进制文件的读写
10.3.2 文件的数据块输入输出函数
2,数据块输入函数 fread()
函数功能:
从 fp所指向的文件中,读取 n个数据项,存放到 p所指向的存储区域 。
若输入操作成功,返回实际读出的数据项个数 。
若文件结束或调用失败,则返回 0。
2009-7-26
38
【 例 10.6】 应用 fwrite与 fread函数建立一个存放学生电话簿的二进制数据文件并读取其中的数据 。
#include "stdio.h"
main( )
{ FILE *fp; int i;
char filename[40]; /* filename用于存放数据文件名 */
struct tel
{ char name[20],tel[9]; }in[5],out[5];
printf("filename,");
gets(filename);
if ((fp=fopen(filename,"wb"))==NULL)
{ printf("Can't open the %s\n",filename);
exit (0);
}
10.3 二进制文件的读写
10.3.2 文件的数据块输入输出函数新建并打开一个二进制文件,并测试是否成功
2009-7-26
39
for(i=0; i<5; i++)
{ printf("name,");
gets(in[i].name);
printf("tel,");
gets(in[i].tel);
}
fwrite(in,sizeof(struct tel),5,fp); /* 文件中写入 5个学生的电话 */
fclose(fp); /* 建立文件结束,关闭文件 */
printf("outfile:\n");
fp=fopen(filename,"rb"); /* 以读方式打开二进制文件 */
fread(out,sizeof(struct tel),5,fp); /* 从文件读取 5个结构体数据 */
printf("name telephone\n");
for(i=0; i<5; i++)
printf("%-20s%-8s\n",out[i].name,out[i].tel);
fclose(fp); /* 读文件结束,关闭文件 */
}
10.3 二进制文件的读写
2009-7-26
40
顺序读写操作在 顺序读写 文件时,文件的 读写指针 由系统 自动 控制,每次读写操作后,系统都会将 读写指针 移到下一个数据的位置。
文件读写操作的内部机制
文件的读写是通过文件系统内部的,读写指针,进行的 。
当 打开 一个文件时,系统自动为该文件分配的 FILE结构体变量中有一个 读写指针 成员,
对该文件的读写操作均通过 读写指针 进行 。
fopen后 读写指针 指向文件中 第 1个 (将要读写的 )字节 。
文件结束 时,读写指针 指向文件 最后 1个字节 的 后面 。
10.3 二进制文件的读写
10.3.3 文件读写指针定位函数
随机读写操作通过 改变 文件 读写指针 的指向,可在文件的 任意 位置进行读写操作 。
2009-7-26
41
常量标识符 值 起始位置
SEEK_SET 0 文件开始位置
SEEK_CUR 1 文件读写指针当前位置
SEEK_END 2 文件结束位置函数功能:
将文件 读写指针 从 whence标识的位置移动 offset个字节,
并将文件结束指示器 清 0。
若移动成功,返回 0;
若移动失败,则返回 非 0值 。
常用的 调用 形式:
fseek(fp,offset,whence);
fp:文件指针变量;
offset,位移量 ( 字节,长整型 ) ;
whence,起始位置标志。
10.3 二进制文件的读写
10.3.3 文件读写指针定位函数
1,文件读写指针移动函数 fseek()
是 正 数,文件 读写指针向文件 尾部 方向移动;
是 负 数向文件 头部 移动该函数仅适用于二进制文件。fseek(fp,30,0)从文件 开始位置 向文件结束方向移动 30个字节
fseek(fp,-10,1)从 当前位置 向文件开始方向移动 10个字节
fseek(fp,-8,2)从文件 结束位置 向文件开始方向移动 8个字节
2009-7-26
42
函数功能:
将文件 读写指针 移到文件开始位置,并将文件结束指示器和错误指示器 清 0。
该函数无返回值 。
常用的 调用 形式:
rewind( fp );
fp:文件指针变量;
10.3 二进制文件的读写
10.3.3 文件读写指针定位函数
2,文件读写指针回绕函数 rewind()
该函数适用于二进制文件和文本文件。
2009-7-26
43
函数功能:
返回 fp指向的文件中的 读写指针 当前位置,即相对于文件开始处的 位移量,单位是字节 。
若调用成功,则返回文件读写指针当前值(长整型);
若调用失败,则返回 -1L。
常用的 调用 形式:
ftell( fp );
fp:文件指针变量;
10.3 二进制文件的读写
10.3.3 文件读写指针定位函数
3,文件读写指针位置函数 ftell()
该函数适用于二进制文件和文本文件。
C 语言程序设计北京科技大学 计算机系第 10章 文 件
2009-7-26
2第 10章 文件
10.1 文件的概念
10.2 文本文件的读写
10.3 二进制文件的读写
2009-7-26
3
文件,存储在 外部存储介质 上相关 数据 的集合 。
例如:程序文件中保存着程序,数据文件中保存着数据 。
*.C C语言的源程序 文本文件
*.OBJ 目标文件 二进制文件
*.EXE 可执行文件 二进制文件
文件的存储特性文件是一个 有序的数据序列 。 C语言把文件作为 一个字符 ( 字节 ) 序列 处理,对文件的存取是以字符 ( 字节 ) 为单位进行的 。
10.1 文件的概述
10.1.1 文件和文件指针
1,什么是文件
2009-7-26
4
设备文件在 C语言中,,文件,的概念被进一步扩大,
把每台与主机相连的 输入输出设备 都看作是一个文件 。 即把实际的物理设备抽象为逻辑文件,它们被称为 设备文件 。
对外部设备的输入输出就是对设备文件的读写 。
10.1 文件的概述
10.1.1 文件和文件指针
1,什么是文件
2009-7-26
5
按文件存储数据的形式
ASCII文件 ( 或称 文本文件 )
ASCII码文件中 每个字节 存放一个 ASCII代码,代表一个字符,此种存储形式便于输出显示,在 DOS操作系统下可以直接阅读 。
二进制文件二进制文件 中的 数据 是按照在内存中的 二进制 存储格式 存放的,此种存储形式节省存储单元 。 二进制文件在 DOS操作系统下不能直接阅读 。
10.1 文件的概述
10.1.1 文件和文件指针
2,文件的种类
2009-7-26
6
例如将整数 1949分别存储在这两种数据文件中 。
ASCII文件,ASCII码二进制文件:补码占用 4个字节占用 2个字节
10.1 文件的概述
10.1.1 文件和文件指针
2,文件的种类
00110001 00111001 00110100 00111001
'1' '9' '4' '9'
00000111 10011101
2009-7-26
7
按照对文件的处理方式
缓冲文件利用缓冲文件系统处理的文件称为缓冲文件 。 系统处理方法是在内存中 为每个正在使用的缓冲文件开辟一个缓冲区,其大小是 512个字节 。 对文件读写数据都通过缓冲区进行 。
非缓冲文件利用非缓冲文件系统处理的文件称为非缓冲文件 。
系统处理非缓冲文件时,不为文件开辟缓冲区,需要程序员自行设计并管理缓冲区 。
83年以后 ANSI C标准中取消了非缓冲文件系统,对文本文件和二进制文件均采用缓冲文件系统进行处理。
10.1 文件的概述
10.1.1 文件和文件指针
2,文件的种类
2009-7-26
8
系统对文件的处理过程就是对文件进行 输入 /输出 操作的过程 。
从文件 读 数据时,先一次性从磁盘文件中读取一批数据到缓冲区,然后再从缓冲区逐个将数据送入变量 。
向文件 写 数据时,也是先将变量中数据送到缓冲区,待缓冲区装满后,再一起存到磁盘文件中 。
10.1 文件的概述
10.1.1 文件和文件指针
3,缓冲文件和文件指针磁盘文件输出输入图 10.2 系统对缓冲文件的处理输入 输出程序区数据区文件缓冲区外存内存
2009-7-26
910.1 文件的概述
10.1.1 文件和文件指针
3,缓冲文件和文件指针
文件类型指针在 缓冲文件系统 中,对每个正在使用的文件都自动分配一个 FILE类型的 结构体变量,用于存放文件的有关信息,如文件号,文件状态,
缓冲区地址和大小等 。
FILE类型是系统定义的,包含在 stdio.h头文件 中在 C语言中,无论对 磁盘文件 还是 设备文件的 读 /写 都要通过 FILE类型的 结构体变量 进行 。
因此 对于每个使用中的磁盘文件 必须 先 定义 一个 FILE类型的 文件指针变量 并指向 此变量 。
FILE *文件指针变量名 ;
typedef struct {
short level; /* fill/empty level of buffer */
unsigned flags; /* File status flags */
char fd; /* File descriptor */
unsigned char hold; /* Ungetc char if no buffer */
short bsize; /* Buffer size */
unsigned char *buffer; /* Data transfer buffer */
unsigned char *curp; /* Current active pointer */
unsigned istemp; /* Temporary file indicator */
short token; /* Used for validity checking */
} FILE; /* This is the FILE object */
2009-7-26
10
标准文件 是外部设备中的三个特殊的设备文件 。 它们的文件指针是系统定义的,并由系统 自动打开和关闭 。 这三个标准文件分别是:
① 标准输入文件,文件指针为 stdin,系统指定为键盘 。
② 标准输出文件,文件指针为 stdout,系统指定为显示器 。
③ 标准错误输出文件,文件指针为 stderr,系统指定为 显示器,输出错误信息 。
10.1 文件的概述
10.1.1 文件和文件指针
4,标准文件
2009-7-26
1110.1 文件的概述
10.1.2 文件的打开与关闭
操作文件的一般步骤打开文件? 读写文件? 关闭文件打开文件,建立 用户程序与文件的 联系,为文件 分配 一个文件缓冲区。
读写文件,是指对文件的 读,写,追加 和 定位 操作。
关闭文件,切断 文件与程序的 联系,释放 文件缓冲区。
C语言的输入输出函数库中提供了大量的函数,用于完成对数据文件的建立、
数据的读写、数据的追加等操作。
在程序中 调用 这些 函数 时,必须先用
include命令包含 stdio.h文件。
2009-7-26
12
常用的 调用 形式:
FILE *fp;
fp = fopen(文件名,文件使用方式 );
文件名,需要打开的文件名称 (字符串 )。
文件使用方式,是具有特定含义的 符号 。
10.1 文件的概述
10.1.2 文件的打开与关闭
1,文件打开函数 fopen()
函数功能:
按指定的 文件使用方式 打开指定的 文件 。
若文件打开 成功,为该文件分配一个文件缓冲区和一个
FILE类型变量,返回一个 FILE类型 指针 ;
若文件打开 失败,返回 NULL。
2009-7-26
13
文本文件的三种基本使用方式
” r”,只读方式为读 (输入 )文本文件打开文件 。 若文件不存在,
返回 NULL。
”w”,只写方式为写 (输出 )文本文件打开文件 。 若文件不存在,
则建立一个新文件;若 文件已存在,则 清空文件 。
” a”,追加方式为写 (输出 )文本文件打开文件 。 若 文件已存在,
则 保持 原来文件的 内容,将新的数据 增加 到原来数据的 后面 ;若文件不存在,则返回 NULL。
10.1 文件的概述
10.1.2 文件的打开与关闭
2009-7-26
14
二进制文件的三种基本使用方式
” rb”,只读方式为读 (输入 )二进制文件打开文件 。 若文件不存在,
返回 NULL。
”wb”,只写方式为写 (输出 )二进制文件打开文件 。 若文件不存在,
则建立一个新文件;若 文件已存在,则 清空文件 。
” ab”,追加方式为写 (输出 )二进制文件打开文件 。 若 文件已存在,
则 保持 原来文件的 内容,将新的数据 增加 到原来数据的后面 ;若文件不存在,则返回 NULL。
10.1 文件的概述
10.1.2 文件的打开与关闭
2009-7-26
1510.1 文件的概述
10.1.2 文件的打开与关闭
文件的其他打开方式
” r+”,可以对 文本文件 进行 读 /写 操作。
若文件不存在返回 NULL;
若文件存在 内容不 被 清空 。
” w+”,可以对 文本文件 进行 读 /写 操作。
若文件已经存在,则先 清空 文件原来的 内容 。
” a+”,可以对 文本文件 进行 读 /追加 操作。
文件内容不会清空。
” rb+”,可以对 二进制文件 进行 读 /写 操作。
” wb+”,可以对 二进制文件 进行 读 /写 操作。
” ab+”,可以对 二进制文件 进行 读 /追加 操作。
2009-7-26
16
检查文件打开操作是否成功
if((fp = fopen("filename","r")) == NULL)
{ printf (”Cannot open file.\n”);
exit(0);
}
检查以 只读 方式打开文件名为 filename的文件是否成功 。
exit函数的作用,结束程序的执行,并将实参 0作为函数返回值传给操作系统。
10.1 文件的概述
10.1.2 文件的打开与关闭
2009-7-26
17
常用的 调用 形式:
FILE *fp;
fclose( fp );
fp:已经打开的文件指针 。
10.1 文件的概述
10.1.2 文件的打开与关闭
2,文件关闭函数 fclose()
函数功能:
关闭 fp指定的文件,释放该文件的缓冲区、
FILE类型变量及文件指针。
若文件关闭成功,则返回 0;
若文件关闭失败,则返回 非 0值 。
2009-7-26
18
常用的 调用 形式:
FILE *fp;
fputc( ch,fp );
ch,需要输出的字符,可以是字符常量或字符变量;
fp:文件指针变量 。
对文本文件的读写操作,必须 按 文件中字符的 先后顺序 进行,只能在操作了第 i个字符之后,才能操作第 i+1个字符 。
在对文件操作时,文件的 读写指针 由系统 自动向后 移动 。
10.2 文本文件的读写
10.2.1 文件的字符输入输出函数
1,字符输出函数 fputc()( 或 putc())
函数功能:
将一个字符( ASCII码)写入到 fp所指向的文件(该文件必须是以写或读写方式打开的)中。
若输出操作成功,函数返回写入的字符;否则,返回 EOF。
系统定义的文本文件结束标志,其值为 (-1)。
① putc函数与 fputc函数的功能相同 。 在 stdio.h文件中被定义为
#define putc(c,f) fputc((c),f)
② 标准文件中用的 putchar函数是 fputc函数的特殊用法,它在 stdio.h文件中被定义为
#define putchar(c) putc((c),stdout)
2009-7-26
19
常用的 调用 形式:
FILE *fp;
ch = fgetc(fp);
ch,可以是字符变量或整型变量;
fp:文件指针变量 。
10.2 文本文件的读写
10.2.1 文件的字符输入输出函数
2,字符输入函数 fgetc()( 或 getc())
函数功能:
从 fp所指向的文件(该文件必须是以读或读写方式打开的)中读取一个字符。
若输入操作成功,函数返回读入的字符;
若文件结束或输入操作失败,则返回 EOF。
① getc函数与 fgetc函数的功能相同 。 在 stdio.h文件中被定义为
#define getc(f) fgetc(f)
② 标准文件中用的 getchar函数是 fgetc函数的特殊用法,它在 stdio.h文件中被定义为
#define getchar( ) getc(stdin)
2009-7-26
20
【 例 10.1】 利用 fputc和 fgetc函数建立一个文本文件,并显示文件中的内容 。
#include <stdio.h>
main( )
{ FILE *fp; /* 定义一个文件指针变量 fp */
int c; /* c为存放字符的变量 */
char filename[40]; /* filename用于存放数据文件名 */
printf("filename,"); /* 提示输入磁盘文件名 */
gets(filename);
if ((fp=fopen(filename,"w"))==NULL)
{ printf("Can't open the %s\n",filename);
exit(0); }
10.2 文本文件的读写
10.2.1 文件的字符输入输出函数测试打开文件是否成功
2009-7-26
21
while ((c=getchar( ))!=EOF)
/*键盘文件结束标志:输入 Ctrl+z,显示 ^Z后回车 */
putc(c,fp); /* 将键盘输入的字符写到文件中 */
fclose(fp); /* 建立文件结束,关闭文件 */
printf("outfile:\n");
fp=fopen(filename,"r"); /* 以读方式打开文本文件 */
while ((c=getc(fp))!=EOF) /* 未读到文件结束标志时 */
putchar(c); /* 在显示器显示读出的字符 */
fclose(fp); /* 读文件结束,关闭文件 */
}
10.2 文本文件的读写
10.2.1 文件的字符输入输出函数
2009-7-26
22
常用的 调用 形式:
FILE *fp;
feof(fp);
fp:文件指针变量 。
10.2 文本文件的读写
10.2.2 文件结束测试函数函数功能:
测试 fp所指向的文件是否已读到文件尾部。
若该文件没有结束,则返回 0;
若文件结束,则返回 非 0值。
对文本文件进行读操作时,例如 fgetc( )返回
EOF,即可作文件结束处理 。 但在二进制文件中 -1
是 合法数据,所以系统提供了一个适用对象更普遍的文件结束测试函数 feof。
2009-7-26
23
例如,复制一个磁盘文件 。
#include <stdio.h>
main()
{ FILE *infp,*outfp; char infile[40],outfile[40];
int ch;
printf("input filename:"); scanf("%s",infile);
printf("output filename:"); scanf("%s",outfile);
if((infp=fopen(infile,"r"))==NULL) /* 打开源文件 */
{ printf("infile open error.\n"); exit(0);}
if((outfp=fopen(outfile,"w"))==NULL)/* 打开目标文件 */
{ printf("outfile open error.\n"); exit(0);}
ch=fgetc(infp); /* 从 源 文件中读一个字符 */
while(!feof(infp)) /* 源 文件未读完 */
{ fputc(ch,outfp); ch=fgetc(infp); }/* 复制文件 */
fclose(infp); fclose(outfp);
}
10.2 文本文件的读写
10.2.2 文件结束测试函数
2009-7-26
24
常用的 调用 形式:
FILE *fp;
fputs(str,fp);
str,需要输出的字符串,可以是字符串常量或字符串指针;
fp:文件指针变量 。
fputs与 puts函数的功能类似,它们的区别:
puts函数能将字符串的结束标志 '\0' 转换成
'\n' 输出,因此字符串在显示器输出后,光标移至下一行;而 fputs函数对字符串结束标志 '\0' 的处理仅仅是将其 舍去 。
10.2 文本文件的读写
10.2.3 文件的字符串输入输出函数
1,字符串输出函数 fputs()
函数功能:
将字符串 ( 不包括字符串结束标志 '\0') 写到文件指针
fp所指向的文件中 。
若输出操作成功,返回 非 0值 ;
若输出操作失败,则返回 0。
2009-7-26
25
常用的 调用 形式:
FILE *fp;
fgets(str,n,fp);
str,字符指针,可以是字符数组名或字符指针变量 ;
n,读取字符个数( n-1)。
fp:文件指针变量 。
10.2 文本文件的读写
10.2.3 文件的字符串输入输出函数
2,字符串输入函数 fgets()
函数功能:
从 fp所指向的文件中,读取 n-1个字符后,加上字符串结束标志 '\0'组成一个字符串,存入字符数组中。
若输入操作成功,返回字符数组的首地址;
若文件结束或输入操作失败,则返回 NULL。
① 从文件读取字符的过程中,如果读到 回车符 ( '\15')
舍去,如果读到 换行符 ( '\12') 仍按字符 读出,再 加上 '\0'
作为一个字符串,同时 结束 文本行 读取操作,函数正常返回 。 当 读到文件结束 时,直接 加上 '\0'作为一个字符串,函数正常返回 。
② fgets与 gets函数的区别,gets函数 以换行符 作为行 结束标志,并 舍去 换行符 。 fgets函数也以换行符作为行的读结束标志,但 换行符 同时还 作为字符串的内容 。 因此可将含有换行符的文本文件看作是由一行一行字符组成的 。
2009-7-26
26
【 例 10.3】 应用 fputs和 fgets函数,建立和读取文本文件 。
#include "stdio.h"
#include "string.h"
main( )
{ FILE *fp; /* 定义一个文件指针变量 fp*/
char filename[40],str[81];
printf("filename,"); /* 提示输入磁盘文件名 */
gets(filename);
if ((fp=fopen(filename,"w"))==NULL)
/* 在磁盘中新建并打开一个文本文件,同时测试是否成功 */
{ printf("Can' t open the %s\n",filename);
exit(0);
}
10.2 文本文件的读写
10.2.3 文件的字符串输入输出函数
2009-7-26
27
while (strlen(gets(str))>0)
/* 键盘输入空串 ( 即仅输入回车 ) 则输入全部结束 */
{ fputs(str,fp); /* 将键盘输入的字符串写到文件中 */
fputc('\n',fp); /* 在文件中加入换行符作为字符串分隔符 */
}
fclose(fp); /* 建立文件结束,关闭文件 */
printf("outfile:\n");
fp=fopen(filename,"r"); /* 以读方式打开文本文件 */
while ((fgets(str,81,fp))!=NULL)
/* 从文件读取字符串并测试文件是否已读完 */
printf("%s",str); /* 将文件中读取的字符串分行显示 */
fclose(fp); /* 读文件结束,关闭文件 */
}
10.2 文本文件的读写
10.2.3 文件的字符串输入输出函数
2009-7-26
28
与标准文件的格式输入输出函数 scanf和 printf相对应,文本文件也有格式输入输出函数 fscanf和
fprintf。 它们的功能和格式基本相同,不同之处在于 scanf和 printf的读写对象是终端 ( 键盘和显示器 ),fscanf和 fprintf的读写对象是磁盘文件 。
常用的 调用 形式:
FILE *fp;
fprintf(fp,格式控制串,输出项参数表 );
fp:文件指针变量 。
格式控制串 和 输出项参数表 的规定和使用方法与
printf函数相同 。
10.2 文本文件的读写
10.2.4 文件的格式输入输出函数
1,格式输出函数 fprintf()
函数功能:
将输出项按指定格式写入 fp所指向的文件中 。
若输出操作成功,返回 写入的字节数 ;
若输出操作失败,则返回 EOF。
2009-7-26
29
常用的 调用 形式:
FILE *fp;
fscanf(fp,格式控制串,地址 表 );
fp:文件指针变量 。
格式控制串 和 地址表 的规定和使用方法与 scanf函数相同 。
10.2 文本文件的读写
10.2.4 文件的格式输入输出函数
2,格式输入函数 fscanf()
函数功能:
按格式控制串所描述的格式,从 fp所指向的文件中读取数据,送到指定的内存地址单元中 。
若输入操作成功,返回实际读出的数据项个数,不包括数据分隔符 。 若没有读数据项,则返回 0。
若文件结束或调用失败,则返回 EOF。
2009-7-26
30
二进制文件 存储信息的形式与 内存 中存储信息的形式是一致的,如果需要在内存与磁盘文件之间频繁交换数据,最好采用二进制文件 。
二进制文件一般是 同类型数据 集合,数据之间无分隔符,每个数据所占字节数是一个定值,因此二进制文件除了可以顺序存取外,还可运用定位函数方便地进行随机存取 。
常用的 调用 形式:
FILE *fp;
putw(w,fp);
w,要输出的整型数据,可以是常量或变量 。
fp:文件指针变量 。
10.3 二进制文件的读写
10.3.1 文件的字输入输出函数
1,字输出函数 putw()
函数功能:
把整型数 w写入 fp所指向的文件( 以写方式打开的二进制文件 )。
若输出操作成功,返回 w值 ;
若输出操作失败,则返回 EOF。
由于 EOF(-1)是一个合法的整数,因此应该用 ferror函数检测函数调用是否出错。
2009-7-26
31
常用的 调用 形式:
FILE *fp;
getw(fp);
fp:文件指针变量 。
10.3 二进制文件的读写
10.3.1 文件的字输入输出函数
2,字输入函数 getw()
函数功能:
从 fp所指向的文件 ( 以读方式打开的二进制文件 )
中读取一个整型数 。
若输入操作成功,返回从文件中读取的整数 。
若文件结束或调用失败,则返回 EOF。
EOF(-1)是 getw函数可能返回的合法值,所以应该用 feof
函数或 ferror函数检测文件是否结束或调用失败。
2009-7-26
32
常用的 调用 形式:
FILE *fp;
ferror(fp);
fp:文件指针变量 。
10.3 二进制文件的读写
10.3.1 文件的字输入输出函数
3,文件操作错误函数 ferror()
函数功能:
检测文件读写是否出错 。
若出错,则指示器 置 1,否则指示器 置 0。
函数返回错误指示器值 。
说明,错误指示器若 置 1后,只有调用 clearerr函数或
rewind函数才能将其 清 0。
2009-7-26
33
常用的 调用 形式:
FILE *fp;
clearerr(fp);
fp:文件指针变量 。
10.3 二进制文件的读写
10.3.1 文件的字输入输出函数
4,清除错误标志函数 clearerr()
函数功能:
将文件的错误指示器和文件结束指示器 清 0。
该函数无返回值 。
2009-7-26
34
【例 10.5】应用 putw和 getw函数建立二进制整型数据文件并读取其中的数据。
#include "stdio.h"
main( )
{ FILE *fp; /* 定义一个文件指针变量 fp*/
char filename[40]; /* filename用于存放数据文件名 */
int i,n1=5,n2,x[5]={10,22,36,48,59},y[5];
printf("filename,");
gets(filename);
if ((fp=fopen(filename,"wb"))==NULL)
/* 新建并打开一个二进制文件,并测试是否成功 */
{ printf("Can' t open the %s\n",filename);
exit(0);
}
10.3 二进制文件的读写
10.3.1 文件的字输入输出函数
2009-7-26
35
putw(n1,fp); /* 向二进制文件写入一个整数 */
for (i=0; i<n1; i++)
putw(x[i],fp); /* 将 x数组的 5个整数写入二进制文件 */
fclose(fp); /* 建立文件结束,关闭文件 */
printf("outfile:\n");
fp=fopen(filename,"rb"); /* 以读方式打开二进制文件 */
n2=getw(fp); /* 从二进制文件读取一个整数 */
for (i=0; i<n2; i++)
{ y[i]=getw(fp); /* 从文件读取一个整数赋给 y数组元素 */
printf("%d ",y[i]);
}
printf("\n");
fclose(fp); /* 读文件结束,关闭文件 */
}
10.3 二进制文件的读写
10.3.1 文件的字输入输出函数
2009-7-26
36
常用的 调用 形式:
fwrite(p,size,n,fp);
p,某类型指针;
size,某类型数据存储空间的字节数(数据项大小);
n,此次写入文件的数据项数;
fp:文件指针变量 。
10.3 二进制文件的读写
10.3.2 文件的数据块输入输出函数
1,数据块输出函数 fwrite()
函数功能:
将 p指向的存储区中 n个数据项写入 fp所指向的文件 。
若输出操作成功,返回 写入的数据项数 ;
若输出操作失败,则返回 0。
运用数据块输入输出函数可建立整型、实型、结构体类型等各种类型的二进制文件。
2009-7-26
37
常用的 调用 形式:
fread(p,size,n,fp);
p,某类型指针;
size,某类型数据存储空间的字节数(数据项大小);
n,此次从文件中读取的数据项数;
fp:文件指针变量 。
10.3 二进制文件的读写
10.3.2 文件的数据块输入输出函数
2,数据块输入函数 fread()
函数功能:
从 fp所指向的文件中,读取 n个数据项,存放到 p所指向的存储区域 。
若输入操作成功,返回实际读出的数据项个数 。
若文件结束或调用失败,则返回 0。
2009-7-26
38
【 例 10.6】 应用 fwrite与 fread函数建立一个存放学生电话簿的二进制数据文件并读取其中的数据 。
#include "stdio.h"
main( )
{ FILE *fp; int i;
char filename[40]; /* filename用于存放数据文件名 */
struct tel
{ char name[20],tel[9]; }in[5],out[5];
printf("filename,");
gets(filename);
if ((fp=fopen(filename,"wb"))==NULL)
{ printf("Can't open the %s\n",filename);
exit (0);
}
10.3 二进制文件的读写
10.3.2 文件的数据块输入输出函数新建并打开一个二进制文件,并测试是否成功
2009-7-26
39
for(i=0; i<5; i++)
{ printf("name,");
gets(in[i].name);
printf("tel,");
gets(in[i].tel);
}
fwrite(in,sizeof(struct tel),5,fp); /* 文件中写入 5个学生的电话 */
fclose(fp); /* 建立文件结束,关闭文件 */
printf("outfile:\n");
fp=fopen(filename,"rb"); /* 以读方式打开二进制文件 */
fread(out,sizeof(struct tel),5,fp); /* 从文件读取 5个结构体数据 */
printf("name telephone\n");
for(i=0; i<5; i++)
printf("%-20s%-8s\n",out[i].name,out[i].tel);
fclose(fp); /* 读文件结束,关闭文件 */
}
10.3 二进制文件的读写
2009-7-26
40
顺序读写操作在 顺序读写 文件时,文件的 读写指针 由系统 自动 控制,每次读写操作后,系统都会将 读写指针 移到下一个数据的位置。
文件读写操作的内部机制
文件的读写是通过文件系统内部的,读写指针,进行的 。
当 打开 一个文件时,系统自动为该文件分配的 FILE结构体变量中有一个 读写指针 成员,
对该文件的读写操作均通过 读写指针 进行 。
fopen后 读写指针 指向文件中 第 1个 (将要读写的 )字节 。
文件结束 时,读写指针 指向文件 最后 1个字节 的 后面 。
10.3 二进制文件的读写
10.3.3 文件读写指针定位函数
随机读写操作通过 改变 文件 读写指针 的指向,可在文件的 任意 位置进行读写操作 。
2009-7-26
41
常量标识符 值 起始位置
SEEK_SET 0 文件开始位置
SEEK_CUR 1 文件读写指针当前位置
SEEK_END 2 文件结束位置函数功能:
将文件 读写指针 从 whence标识的位置移动 offset个字节,
并将文件结束指示器 清 0。
若移动成功,返回 0;
若移动失败,则返回 非 0值 。
常用的 调用 形式:
fseek(fp,offset,whence);
fp:文件指针变量;
offset,位移量 ( 字节,长整型 ) ;
whence,起始位置标志。
10.3 二进制文件的读写
10.3.3 文件读写指针定位函数
1,文件读写指针移动函数 fseek()
是 正 数,文件 读写指针向文件 尾部 方向移动;
是 负 数向文件 头部 移动该函数仅适用于二进制文件。fseek(fp,30,0)从文件 开始位置 向文件结束方向移动 30个字节
fseek(fp,-10,1)从 当前位置 向文件开始方向移动 10个字节
fseek(fp,-8,2)从文件 结束位置 向文件开始方向移动 8个字节
2009-7-26
42
函数功能:
将文件 读写指针 移到文件开始位置,并将文件结束指示器和错误指示器 清 0。
该函数无返回值 。
常用的 调用 形式:
rewind( fp );
fp:文件指针变量;
10.3 二进制文件的读写
10.3.3 文件读写指针定位函数
2,文件读写指针回绕函数 rewind()
该函数适用于二进制文件和文本文件。
2009-7-26
43
函数功能:
返回 fp指向的文件中的 读写指针 当前位置,即相对于文件开始处的 位移量,单位是字节 。
若调用成功,则返回文件读写指针当前值(长整型);
若调用失败,则返回 -1L。
常用的 调用 形式:
ftell( fp );
fp:文件指针变量;
10.3 二进制文件的读写
10.3.3 文件读写指针定位函数
3,文件读写指针位置函数 ftell()
该函数适用于二进制文件和文本文件。