Professional Documents
Culture Documents
第九次课
文 件
( FILE )
学过的文件库函数
FILE *fopen(“ 文件名”,“操作方式” );
int fclose(FILE *fp)
两个特殊的标识符
FILE 文件类型名
EOF 文件结束符号常数( -1 )
课堂练习
程序 filecopy.c 的功能是:实现文件的复制,源文件名和目标文件名由命令行参数
( EOF )即结束。
2. 返回值:正常时返回读取字符串的首地址;
加‘ \0’ ), fp 为读取文件的文件指针
写一个字符串── fputs( )
函数原型:
int fputs(char *s,FILE *fp)
if((fp=fopen("d:\\in.txt","r"))==NULL)
{
printf("cann't open file");
exit(0);
}
if(fgets(string,81,fp)!=NULL)
fputs(string,stdout);
fclose(fp);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
[ 案例 3+] 将磁盘文件中 int main(void)
的字符串读出,并存储在 {
FILE *fp,*fp1;
另外一个文件中。
char string[81];
if((fp=fopen("d:\\in.txt","r"))==NULL)
{
printf("cann't open file");
exit(-1);
}
if((fp1=fopen("d:\\write.txt","w"))==NULL)
{
printf("cann't open file");
exit(-1);
}
while(fgets(string,81,fp)!=NULL)
fputs(string,fp1);
fclose(fp);
fclose(fp1);
return 0;
} 8
案例分析
读一个数据块── fread( )
函数原型:
int fread(void *buffer , int size , int count , FILE *fp) ;
1. 功能:从 fp 所指向的文件读一个数据块
size 为读取的字节数;
count 为读取的次数;
fp 为文件类型指针。
10
写一个数据块── fwrite( )
函数原型:
int fwrite(void *buffer , int size , int count , FILE *fp) ;
1. 功能:向 fp 所指文件写一个数据块
分析(构思):
( 1 )建立学生信息的结构体;
( 2 )定义文件指针;
( 3 )定义结构体数组并初始化(为方便调试而作);
( 4 )将学生信息写入文件,写完后关闭该文件(编写函数)
;
( 5 )再次打开该文件,读出所有学生信息,读完后关闭该文
件(编写函数) ;
( 6 )显示学生信息到屏幕上(编写函数) 。
typedef struct student
{ char name[10]; int save( StudType stud[] ,int n);
int num; int readfile(StudType stud[] );
int age; void display(StudType stud[],int
}StudType; n);
int main(void)
{
StudType stud[10]={{“ 大师兄” ,201008,18},
{“ 二师弟” ,201009,19},
{“ 师父” ,201010,10}};
StudType result_stud[10];
int n;
if( save(stud,3) ==0) printf("save error");
if((n= readfile(result_stud) )==0) printf("save error");
display(result_stud,n);
return 0;
}
int save(StudType stud[],int n)
{ FILE *fp;
int count;
if((fp=fopen(“d:\\student.dat","wb"))==NULL)
{
printf(" 打不开文件 \n");
return 0;
}
if((count=fwrite(stud,sizeof(StudType),n,fp))==0)
printf(" 写操作错误 \n");
fclose(fp);
return count;
}
int readfile(StudType stud[])
{ FILE *fp;
int n;
int count=0;
if((fp=fopen(“d:\\student.dat”, “rb”))==NULL)
{
printf(“ 打不开文件 \n” );
return 0;
}
n=fread(stud,sizeof(StudType),1,fp);
while(n==1)
{
count++;
n=fread(&stud[count],sizeof(StudType),1,fp);
}
fclose(fp);
return count;
}
void display(StudType stud[],int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%-10s %4d %4d\n",stud[i].name,
stud[i].num,stud[i].age);
}
printf("\n____________________________________\
n");
}
课堂练习
在以上设计的基础上,再编写一个函数实现追加一个学
生记录到文件中。
写文件;
关闭文件;
对文件进行格式化读/写── fscanf( ) 和 fprintf( )
函数
与 scanf( ) 和 printf( ) 函数的功能相似,区别在于: fscanf( ) 和
fprintf( ) 函数的操作对象是指定文件,而 scanf( ) 和 printf( ) 函数的操作
对象是标准输入( stdin )输出( stdout )文件。
例如, ......
int i=3; float f=9.80;
......
fprintf(fp,"%2d,%6.2f", i, f);
......
fprintf( ) 函数的作用是,将变量 i 按 %2d 格式、变量 f 按 %6.2f 格式,
以逗号作分隔符,输出到 fp 所指向的文件中:□ 3,□□9.80 (□表示 1 个
空格)。
用 fprintf 和 fscanf 实现学生信息文件的读和写
但为方便起见,依下列原则选用:
3 .读 / 写一个(或多个)不含格式的数据时:
4 .读 / 写一个(或多个)含格式的数据时:
个(或一组)数据后,系统自动将位置指针移动到下一个读写位
置上。
读写方式
顺序读写:位置指针按字节位置顺序移动
随机读写:位置指针按需要移动到任意位置
25
rewind( ) 函数
26
fseek( ) 函数
1. 函数原型: int fseek( 文件指针,位移量,参照点 );
int fseek(FILE *fp,long int offset,int whence)
2. 功能:将指定文件的位置指针,从参照点开始,移动指定的字节数。
3. 参数: fp 为文件指针,
whence 为参照点用 0 (文件头)、 1 (当前位置)和 2 (文件尾)表示
在 ANSI C 标准中,还规定了下面的名字:
SEEK_SET── 文件头, SEEK_CUR── 当前位置, SEEK_END── 文件尾
Offset 为位移量:以参照点为起点,正向偏移(当位移量 > 0时)或负向偏
移(当位移量 < 0时)的字节数。位移量一般被要求是 long 型数据,这样当
文件的长度大于 64K 时不出问题。
4. 返回值:成功为 0 ,失败为非 0.
注: fseek( ) 函数一般用于二进制文件。
注意:位移量一般被要求是 long 型数据。
fseek 函数调用的几个例子:
fseek(fp,100L,SEEK_SET); 将指针从文件头正向移动 100 个字节
fseek(fp,100L , SEEK_CUR); 将位置指针从当前位置正向移动
100 个字节
fseek(fp,-100L,SEEK_END) ; 将位置指针从文件末尾处负向偏移
100 个字节
返回文件当前位置的函数 ftell( )
由于文件的位置指针可以任意移动,也经常移动,往往容易迷
失当前位置, ftell( ) 就可以解决这个问题。
1 .用法: long int ftell( 文件指针 );
2 .功能:返回文件位置指针的当前位置(用相对于文件头的
位移量表示)。
如果返回值为 -1L ,则表明调用出错。
例如 :
offset=ftell(fp) ;
if(offset= = - 1L)
printf(“ftell( ) error\n”) ;
思考:如何获取文件长度(字节数)?
29
#include <stdio.h>
[ 案例 5] 磁盘文 #include <stdlib.h>
件上有 3 个学生 typedef struct student_type
数据,要求读入 {
char name[10];
第 2 学生数据并 int num;
显示。
int main(void) int age;
{ }STU;
int i=0;
FILE *fp;
STU st;
STU stud[]={{"mary",20110001,18},{"rose",20110002,19},{"mary",20110003,18}};
if((fp=fopen("d:\\stu.dat","wb+"))==NULL)
{
printf("can't open file\n");
exit(1);
}
fwrite(stud,sizeof(STU),3,fp);
fseek(fp,1*sizeof(STU),SEEK_SET);
fread(&st,sizeof(STU),1,fp);
printf("%s %d %d \n", st.name,st.num,st.age);
fclose(fp);
return 0;
30
}
出错检测
ferror( ) 函数
在调用输入输出库函数时,如果出错,除了函数返回值有所反映外,也可利用 ferror( )
函数来检测。
1 .用法: int ferror( 文件指针 ) ;
2 .功能:如果函数返回值为 0 ,表示未出错;如果返回一个非 0 值,表示出错。
( 1 )对同一文件,每次调用输入输出函数均产生一个新的 ferror( ) 函数值。因此在调用
了输入输出函数后,应立即检测,否则出错信息会丢失。
( 2 )在执行 fopen( ) 函数时,系统将 ferror( ) 的值自动置为 0 。
clearerr( ) 函数
1 .用法: void clearerr( 文件指针 ) ;
2 .功能:将文件错误标志(即 ferror() 函数的值)和文件结束标志(即 feof( ) 函数的值)
置为 0 。
对同一文件,只要出错就一直保留,直至遇到 clearerr( ) 函数或 rewind( ) 函数,或其它
任何一个输入输出库函数。
31
文件操作小结
分类 函数名 功能
打开文件 fopen( ) 打开文件
关闭文件 fclose( ) 关闭文件
fseek( ) 改变文件位置的指针位置
文件定位 rewind( ) 使文件位置指针重新置于文件开头
ftell( ) 返回文件位置指针的当前值
fgetc( ) 从指定文件取得一个字符
fputc( ) 把字符输出到指定文件
fgets( ) 从指定文件读取字符串
fputs( ) 把字符输出到指定文件
文件读写 fread( ) 从指定文件中读取数据项
fwrite( ) 把数据项写到指定文件
fscanf( ) 从指定文件按格式输入数据
fprintf( ) 按指定格式将数据写到指定文件中
feof( ) 若到文件末尾,函数值为真(非 0 )
文件状态 ferror( ) 若对文件操作出错,函数值为真(非 0 )
clearerr( ) 使 feof( ) 和 ferror( ) 函数值置零
课后作业
所有课堂程序代码
实验 11
作业 4
33