版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第9章文件9.1文件概述9.2文件指针9.4文件的读/写9.5文件的定位9.6文件检测函数
文件是计算机中经常使用的一个重要概念。本章在叙述文件概念的基础上,介绍文
件的基本操作和应用,讲解文件操作的基本过程,使读者熟悉C语言中有关文件处理的库函数。
学习重点:
文件指针
文件的读写
9.1.1文件的定义
文件是指存储在外部介质(如磁盘和磁带等外存储器)上的数据或信息的集合。例如:源程序文件中保存着源程序,文本文件中保存着文本数据,声音文件中保存着声音数据等。
为标识一个文件,每个文件都必须有一个文件名,其一般结构为:
主文件名[.扩展名]9.1文件概述文件命名规则遵循操作系统的约定。计算机通过文件名对文件进行读、写、修改和删除等操作。
C语言实现文件操作的途径主要有两种:一是通过操作系统。由于操作系统是以文件为单位对数据进行管理的,因此可以直接引用操作系统的系统调用,这属于低级的操作,使用方法相对复杂,在现在的程序设计中已经很少使用;二是通过由C语言编译系统提供的一套用于文件操作的库函数,也称为“标准输入/输出库”。本章介绍通过标准输入/输出库来使用文件。9.1.2文件的分类
可以从不同的角度对C语言的文件进行分类:
(1)从用户的角度看,文件可分为普通文件和设备文件。
普通文件是指驻留在磁盘或其他外部介质上的数据集合,可以是源文件、目标文件、可执行程序,也可以是一组待输入处理的原始数据或一组输出的结果。
设备文件是指与主机相连的各种外部设备,如显示器、打印机、键盘等。在操作系统中,外部设备也被看做是一个文件,并对其进行管理,将它们的输入、输出等同于对磁盘文件的读和写。通常把显示器定义为标准输出文件,一般情况下在屏幕上显示有关信息就是向标准输出文件输出。如前面经常使用的printf、putchar函数就是这类输出。
键盘通常被指定为标准的输入文件,从键盘上输入就意味着从标准输入文件上输入数据。scanf、getchar函数就属于这类输入。
(2)从数据组织形式的角度来看,文件可分为ASCII文件和二进制文件。数据的组织形式是指数据在磁盘上的存储形式。
ASCII文件又称文本(TEXT)文件,它的数据是采用ASCII码形式存储的。每一个字节放一个ASCII代码,代表一个字符。这样的好处是便于对字符进行逐个处理,也便于输出字符。劣势是占存储空间较多,而且要花费转换时间(二进制形式与ASCII码间的转换)。
二进制文件与ASCII文件不同,它是把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放。这样可以节省外存空间和转换时间,但一个字节并不对应一个字符,不能直接输出字符形式。图9-1int型十进制数1024的存储形式例如:int型的十进制数1024用ASCII形式输出要占用4个字节;若按二进制形式输出则只占用2个字节。如图9-1所示。
(3)从C语言对文件处理方法的角度来看,可以将文件分为缓冲文件系统和非缓冲文件系统。
所谓“缓冲文件系统”,是指系统自动地在内存区为每个正在使用的文件开辟一个缓冲区。从内存向磁盘输出数据必须先送到内存中的缓冲区,装满缓冲区后再一起送到磁盘去。如果从磁盘向内存读入数据,则一次从磁盘文件将一批数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(给程序变量),如图9-2所示。缓冲区的大小由各个具体的C语言版本确定,一般为512字节。
图9-2文件的写入—写出所谓“非缓冲文件系统”,是指系统不自动开辟确定大小的缓冲区,而由程序为每个文件设定缓冲区。
用缓冲文件系统进行的输入/输出又称为高级磁盘输入/输出,用非缓冲进行的输入/输出又称为低级输入/输出系统。ANSIC标准不采用非缓冲文件系统,而只采用缓冲文件系统。也就是说,既用缓冲文件系统处理文本文件,也用它来处理二进制文件。
本章只介绍ANSIC标准中的缓冲文件系统及其相关的库函数。
在缓冲文件系统中,涉及到的关键概念是“文件指针”。
对每个正在使用的文件都要定义一个FILE结构体类型变量,该变量用于存放文件的有关信息,如文件名、文件状态等。9.2文件指针
FILE结构体类型不需要用户自己定义,它是由系统事先定义的,固定包含在头文件stdio.h中。其类型定义如下:
typedef
struct
{
short level; /*缓冲区“满”或“空”的程度*/
unsigned flags; /*文件状态标志*/
char fd; /*文件描述符*/
unsignedchar hold; /*如无缓冲区不读取字符*/
short bsize; /*缓冲区的大小*/
unsignedchar *buffer; /*数据缓冲区的位置*/
unsignedchar *curp; /*当前读写位置*/
unsigned istemp; /*临时文件,指示器*/
short token; /*用于有效性检查*/
}FILE;
FILE是该结构体类型的类型名。在C程序中,凡是要对已打开的文件进行操作,都要通过指向该文件的FILE结构体变量的指针。为此,需要在程序中定义一个FILE型(文件型)指针变量。
文件型指针变量定义的形式为:
FILE*文件型指针名;
例如:
FILE*fp;
fp定义为一个FILE结构体类型的指针变量。通过fp可寻找存放某个文件信息的结构体变量,然后按结构体变量提供的信息找到该文件,从而实施对文件的操作。习惯上也笼统地把fp称为指向一个文件的指针。
文件在进行读/写操作之前要先打开,使用完毕要关闭。所谓打开文件,实际上是建立文件的各种有关信息,并使文件指针指向该文件,以便进行其他操作。关闭文件则断开指针与文件之间的联系,也就禁止再对该文件进行操作。
在C语言中,文件操作都是由库函数来完成的。9.3文件的打开与关闭9.3.1文件打开函数(fopen)
fopen函数用来打开一个文件,其调用的一般形式为:
文件指针名=fopen(文件名,使用文件方式);
其中,“文件名”是被打开文件的文件名,它是字符串常量或字符串数组;“使用文件方式”是指文件的类型和操作要求;“文件指针名”是一个FILE类型的指针变量,它保存fopen函数返回指向被打开文件的指针。例如:
FILE*fp;
fp=("file1","r");
其功能是在当前目录下打开文件file1,只允许进行“读”操作,并使fp指向该文件。
又如:
FILE*fp;
fp=("c:\\a.dat","rb");其功能是打开C盘根目录下的文件a.dat,这是一个二进制文件,只允许按二进制方式进行读操作。
文件使用方式共有12种,表9-1给出了它们的符号和含义。表9-1文件使用方式的符号和含义对于使用文件方式有以下几点说明:
(1)使用文件方式由“r”、“w”、“a”、“b”和“+”五个字符组成,各字符的含义分
别是:
r(read) 读
w(write) 写
a(append) 追加
b(banary) 二进制文件
+ 读和写
(2)凡用“r”打开一个文件时,该文件必须已经存在,且只能从该文件读出。
(3)用“w”打开的文件只能向该文件写入。若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已经存在,则将该文件删去,重建一个新文件。
(4)若要向一个已存在的文件追加新的信息,只能用“a”方式打开文件。
(5)用“r+”、“w+”、“a+”方式打开的文件可以用来输入和输出数据。用“r+”方式时该文件应该已经存在,以便能向计算机输入数据。用“w+”方式则新建立一个文件,先向此文件写数据,然后可以读此文件中的数据。用“a+”方式打开的文件,原来的文件不被删去,位置指针移到文件末尾,则可以添加,也可以读。
(6)在打开一个文件时,如果出错,fopen将返回一个空指针值NULL。在程序中可以用这一信息来判别是否完成打开文件的工作,并作相应的处理。因此常用下面的方法打开一个文件:
if((fp=fopen("file1","r")==NULL)
{
printf("Cannotopenfile1!\n");
exit(0);
}
这段程序的意义是:如果fopen返回的指针为空,则表示不能打开文件file1,并给出提示信息“Cannotopenfile1!”,然后执行exit(0)退出程序。如果fopen返回的指针不为空,则继续执行“{}”后面的语句。
(7)把一个文本文件读入内存时,要将ASCII码转换成二进制码;而把文件以文本方式写入磁盘时,也要把二进制码转换成ASCII码。因此,对文本文件的读/写要花费较多的转换时间,对二进制文件的读/写则不存在这种转换。
(8)在程序开始运行时,系统自动打开三个标准文件,即标准输入、标准输出、标准出错输出,并分别用文件指针stdin、stdout、stderr指向它们。9.3.2文件关闭函数(fclose)
文件一旦使用完毕,应用文件关闭函数把文件关闭。文件关闭后,文件指针变量不再指向该文件,此后不能再通过该指针对该文件进行读/写操作,除非再次打开,使该指针变量重新指向该文件。
fclose函数调用的一般形式为:
fclose(文件指针);
例如:
fclose(fp);
正常完成关闭文件操作时,fclose函数返回值为0。如返回非零值则表示有错误发生。在程序终止之前必须关闭所有使用的文件。如果不关闭,可能会造成数据丢失。因为在向文件写数据时,先将数据输到缓冲区,待缓冲区充满后才写到磁盘上的文件中。如果当数据未充满缓冲区而程序结束运行,就会将缓冲区中的数据丢失。而用fclose函数关闭文件,将把缓冲区中的数据写到磁盘文件,然后释放文件指针变量。
文件打开之后,就可以对它进行读/写了。C语言编译系统提供了多种文件读/写的函数,它们都包含在头文件stdio.h中。9.4文件的读/写9.4.1字符读/写函数fgetc和fputc
1.读字符函数fgetc()
fgetc函数的功能是从指定的文件中读取一个字符,其调用形式为:
ch=fgetc(fp);
其中,fp为文件型指针变量,ch为字符变量。fgetc函数返回读取的字符,并把它赋给ch。若读取字符时文件已经结束,则函数返回文件结束标记EOF。EOF是在头文件stdio.h中定义的符号常量,其值为
-1。例如,要从磁盘文件中顺序读入字符并在屏幕上显示,可通过调用fgetc函数实现:
while((c=fgetc(fp))!=EOF)
putchar(c);
注意:文件结束标记EOF是不可输出字符,不能在屏幕上显示。由于字符的ASCII码不可能出现
-1,因此EOF定义为
-1是合适的。
对于fgetc函数的使用有以下几点说明:
(1)在fgetc函数调用中,读取的文件必须是以读或读写方式打开的。
(2)读取字符的结果也可以不向字符变量赋值,
例如:
fgetc(fp);
但是读出的字符不能保存。
(3)在文件内部有一个位置指针,用来指向文件的当前读写字节。在文件打开时,该指针总是指向文件的第一个字节。使用fgetc
函数后,该位置指针将向后移动一个字节,因此可连续多次使用fgetc函数来读取多个字符。
应注意:文件指针和文件内部的位置指针不是一回事。文件指针是指向整个文件的,须在程序中定义说明,只要不重新赋值,文件指针的值是不变的。文件内部的位置指针用以指示文件内部的当前读写位置,每读写一次,该指针均向后移动,它不需在程序中定义说明,而是由系统自动设置的。
(4)现在ANSIC已允许用缓冲文件系统处理二进制文件,而读入某一个字节中的二进制数据的值有可能是-1,而这又恰好是EOF的值,这就出现了读入的有用数据却被处理为“文件结束”的情况。为了解决这个问题,ANSIC提供一个feof函数来判断文件是否真的结束。feof(fp)用来测试fp所指向的文件当前状态是否“文件结束”,如果是,函数feof(fp)的值为1(真),否则为0(假)。
如果想顺序读入一个二进制文件中的数据,可以用
while(!feof(fp))
c=fgetc(fp);当未遇文件结束,feof(fp)的值为0,!feof(fp)的值为1,读入一个字节的数据赋给整型变量c(可以接着对这些数据进行处理)。直到遇文件结束,feof(fp)的值为1,!feof(fp)的值为0,也就不再执行while循环。
这种方法也适用于文本文件。
【例9-1】在屏幕上显示文本文件的内容。
#include<stdio.h>
#indude<process.h>
voidmain()
{
FILE*fp;
charfilename[20],ch;
printf("Pleaeinputfilename:");
scanf("%s",filename); /*输入文件名*/
if((fp=fopen(filename,"r"))==NULL) /*打开文件*/
{
printf("Cannotopen%s!\n",filename); /*出错处理*/
exit(0);
}
while((ch=fgetc(fp))!=EOF) /*从文件中读字符*/
putchar(ch); /*显示从文件读入的字符*/
fclose(fp); /*关闭文件*/
}程序运行时,先提示输入文件名(需包含路径,否则该文件应该在程序根目录下),然后程序以只读方式打开该文件。如果正确打开文件,则读出每个字符,并显示在屏幕上,然后关闭文件;如果打开文件时出错,则显示不能打开文件的信息,然后退出程序。
2.写字符函数fputc()
fputc函数的功能是将一个字符输出到指定文件中,其调用形式为:
fputc(ch,fp);
其中,ch是要输出的字符(可为字符常量或字符变量),fp为文件型指针变量。函数将字符(ch的值)输出到fp所指向的文件中。如果输出成功,则返回值就是输出的字符;如果输出失败,则返回EOF。
前面介绍过的putchar函数其实就是从fputc函数派生出来的。putchar(c)是用#define定义的宏:
#defineputchar(c)fputc(c,stdout)其中,stdout是系统定义的文件指针变量,它指向终端输出;fputc(c,stdout)的作用是将c的值输出到终端。用宏putchar(c)比写fputc(c,stdout)简单一些,从用户的角度,可以把putchar(c)看做函数而不必严格地称它为宏。
对于fputc函数的使用有以下几点说明:
(1)被写入的文件可以用写、读写、追加方式打开。用写或读写方式打开一个已存在的文件时,将清除原有的文件内容。写入字符从文件首开始。如需保留原有文件内容,希望把写入的字符存放到文件末,必须以追加方式打开文件。被写入的文件若不存在,则创建该文件。
(2)每写入一个字符,文件内部位置指针向后移动一个字节。
【例9-2】编程完成文本文件的复制。
#include<stdio.h>
voidmain()
{
FILE*fp1,*fp2;
charfile1[20],file2[20],ch;
printf("Pleaseinputfilename1:");
scanf("%s",file1);
printf("Pleaseinputfilename2:");
scanf("%s",file2);
if((fp1=fopen(file1,"r"))==NULL)/*以“只读”方式打开文件1*/
{
printf("Cannotopen%s!\n",file1);
exit(0);
}
if((fp2=fopen(file2,"w"))==NULL) /*以“写”方式打开文件2*/
{
printf("Cannotopen%s!\n",file2);
exit(0);
}
while((ch=fgetc(fp1))!=EOF) /*从文件fp1中读字符*/
fputc(ch,fp2); /*写入文件fp2中*/
fclose(fp1); /*关闭两个文件*/
fclose(fp2);
}
程序运行结果为:
Pleaseinputfilename1:e:\test.txt<回车>
Pleaseinputfilename2:e:\test1.txt<回车>
test.txt为原有文件,在E盘根目录下;test1.txt为新复制的文件,也在E盘根目录下。
也可以在输入命令行时把两个文件名一起输入。这时要用到main函数的参数。程序可改为:
#include<stdio.h>
voidmain(int
argc,char*argv[])
{
FILE*fp1,*fp2;
charch;
if(argc!=3)
{
printf("Mustinputtwofilenames!\n");
exit(0);
}
if((fp1=fopen(argv[1],"r"))==NULL)/*以“只读”方式打开文件1*/
{
printf("Cannotopen%s!\n",argv[1]);
exit(0);
}
if((fp2=fopen(argv[2],"w"))==NULL)/*以“写”方式打开文件2*/
{
printf("Cannotopen%s!\n",argv[2]);
exit(0);
}
while((ch=fgetc(fp1))!=EOF) /*从文件fp1中读字符*/
fputc(ch,fp2); /*写入文件fp2中*/
fclose(fp1); /*关闭两个文件*/
fclose(fp2);
}假设该程序的源文件名为MyCopy.c,经编译、连接后得到的可执行文件名为
MyCopy.exe,
把它放在C盘根目录下,
则在DOS命令提示符窗口中,
可按如下方式复制
文件:
C:\>MyCopy
e:\test.txte:\test1.txt<回车>9.4.2字符串读/写函数fgets和fputs
fgets()和fputs()函数是以字符串为单位对文件进行读/写的,由于这两个函数在使用中往往是一次读/写一行,所以也称为行读/写函数。
1.读字符串函数fgets()
fgets函数的功能是从指定的文件中读一个字符串到字符数组中,其调用形式为:
fgets(字符数组名,n,文件指针);
其中,n是一个正整数,表示从文件中读出n-1个字符,并在最后一个字符后加上串结束标志
'\0',将它们一起放入字符数组中。如果在读入n-1个字符结束之前遇到换行符或EOF,读入即结束。如果操作正确,函数的返回值为字符数组的首地址;如果文件结束或出错,则函数的返回值为NULL。
【例9-3】从D盘根目录下的test.txt文件中读入一个含10个字符的字符串。
#include<stdio.h>
voidmain()
{
FILE*fp;
charstr[11];
if((fp=fopen("d:\\test.txt","r"))==NULL)
{
printf("Cannotopenfile!");
exit(0);
}
fgets(str,11,fp);
printf("\n%s\n",str);
fclose(fp);
}本例定义了一个字符数组str共11个字节,在以只读文件方式打开D盘上文件test.txt后,从中读出10个字符送入str数组,在数组最后一个单元内将加上
'\0',然后在屏幕上显示输出str数组。
2.写字符串函数fputs()
fputs函数的功能是向指定的文件写入一个字符串,其调用形式为:
fputs(字符串,文件指针);
其中,“字符串”可以是字符串常量,也可以是字符数组名或字符型指针变量,例如:
fputs("abcd",fp);
其意义是把字符串
"abcd"
写入fp所指的文件之中。
【例9-4】从键盘输入若干行字符存入D盘根目录下的文件file.txt中。
#include<stdio.h>
#include<string.h>
voidmain()
{
FILE*fp;
charstr[81];
if((fp=fopen("D:\\file.txt","w"))==NULL)
{
printf("Cannotopenfile!\n");
exit(0);
}
while(strlen(gets(str))>0)
{
fputs(str,fp);fputs("\n",fp);
}
fclose(fp);
}程序以只写方式打开D盘根目录下的文件file.txt后,用一个while循环来完成从键盘输入字符串,并把字符串写到文件中。gets(str)表示从键盘获取字符串,并把它保存到字符数组str中。strlen()函数测试输入的字符串的字符个数,如果大于0,则用函数fputs把保存在str中的字符串写到文件中。fputs("\n",fp)表示向文件中输入一个换行符,使位置指针移到下一行开始。9.4.3数据块读/写函数fread和fwrite
C语言提供了读写整块数据的函数fread和fwrite。它们可用来读/写一组数据,如一个数组元素,一个结构体变量的值等。
读数据块函数调用的一般形式为:
fread(buffer,size,count,fp);
写数据块函数调用的一般形式为:
fwrite(buffer,size,count,fp);
其中:buffer是一个指针。在fread函数中,它表示存放输入数据的首地址;在fwrite函数中,它表示存放输出数据的首地址。size表示数据块的字节数。count表示要读/写的数据块块数。fp表示文件指针。
例如:
fread(fa,4,5,fp);
其意义是从fp所指的文件中,每次读4个字节(一个实数)送入实数数组fa中,连续读5次,即读5个实数到fa中。
【例9-5】定义一个包含学生信息的结构体变量,其中包括学号、姓名、年龄、班级等几个成员。然后从键盘输入3个学生的信息,并把它们存储到D盘根目录下的文件student.dat中。
源程序如下:
#include<stdio.h>
structstudent
{
intnumber;
charname[10];
intage;
charclass[10];
};
voidmain()
{
FILE*fp;
structstudents;
inti,size;
size=sizeof(structstudent);
if((fp=fopen("D:\\student.dat","wb"))==NULL)
{
printf("Cannotopenthefile!");
exit(0);
}
for(i=0;i<3;i++)
{
scanf("%d%s%d%s",&s.number,&,&s.age,&s.class);
fwrite(&s,size,1,fp);
}
fclose(fp);
}程序运行结果为:
101wang20200203<回车>
102zeng19200203<回车>
103zhang19200203<回车>
该程序定义了一个结构体类型student。先打开或建立D盘上的二进制文件student.dat,然后用一个for循环依次输入3个学生的学号、姓名、年龄和班级。每输入一个学生的信息,就把它写入文件。sizeof(structstudent)是求结构体类型student的长度(字节数)。fwrite(&s,size,1,fp)是把结构体变量的内容写入fp所指的文件中,注意必须传递变量s的地址给函数,“1”表示输出1个结构体变量的内容。
【例9-6】D盘根目录下的文件student.dat中存储有学生的学号、姓名、年龄、班级等信息,编写程序把年龄小于20岁的学生信息显示出来。
源程序如下:
#include<stdio.h>
structstudent
{
intnumber;
charname[10];
intage;
charclass[10];
};
voidmain()
{
FILE*fp;
structstudents;
intsize;
size=sizeof(structstudent);
if((fp=fopen("D:\\student.dat","rb"))==NULL)
{
printf("Cannotopenthefile!");
exit(0);
}
while(!feof(fp))
{
fread(&s,size,1,fp);
if(s.age<20)
printf("%d%s%d%s\n",s.number,,s.age,s.class);
}
fclose(fp);
}
程序运行结果为:
102zeng19200203
103zhang192002039.4.4格式化读/写函数fscanf和fprintf
函数fscanf和fprintf与前面使用的scanf和printf功能相似,都是格式化读/写函数。两者的区别在于:fscanf和fprintf的读/写对象是磁盘文件;scanf和printf的读/写对象是标准输入/输出设备(键盘/显示器)。
fscanf函数和fprintf函数的调用形式分别为:
fscanf(文件指针,格式字符串,输入表列);
fprintf(文件指针,格式字符串,输出表列);
例如:
fscanf(fp,"%d%s",&i,s);该语句是从fp所指的文件中读入一个整数和一个字符串,分别送给整型变量i和字符数组s。
又如:
fprintf(fp,"%d%c",j,ch);
该语句把整型变量j和字符变量ch的值依次写入fp所指的文件中。
可以看到,函数fscanf和fprintf与函数scanf和printf的格式也非常类似,只是多了文件指针项,用于指明要操作的文件,而格式字符串和输入/输出表列与scanf和printf中的规则完全一致。【例9-7】从键盘输入一个字符串和一个十进制整数,并将它们写入test.txt文件中,然后再从test.txt文件中读出并显示在屏幕上。
源程序如下:
#include<stdio.h>
voidmain()
{
chars[81];
inta;
FILE*fp;
if((fp=fopen("test.txt","w"))==NULL) /*以写方式打开文本文件*/
{
printf("Cannotopenfile.\n");
exit(0);
}
printf("Pleaseinputastringandainteger:\n");
fscanf(stdin,"%s%d",s,&a); /*从标准输入设备(键盘)上读取数据*/
fprintf(fp,"%s%d",s,a); /*以格式输出方式写入文件*/
fclose(fp); /*写文件结束关闭文件*/
printf("Begoingtoprintastringandaintegerfromthefiletest.txt!\n");
if((fp=fopen("test.txt","r"))==NULL) /*以读方式打开文本文件*/
{
printf("Cannotopenfile.\n");
exit(0);
}
fscanf(fp,"%s%d",s,&a); /*以格式输入方式从文件读取数据*/
fprintf(stdout,"%s%d\n",s,a); /*将数据显示到标准输出设备(屏幕)上*/
fclose(fp); /*读文件结束关闭文件*/
}
程序运行结果为:
Pleaseinputastringandainteger:
abce12359<回车>
Begoingtoprintastringandaintegerfromthefiletest.txt!
abce12359
该程序在从键盘输入数据时使用fscanf(stdin,"%s%d",s,&a),它同scanf("%s%d",s,&a)的功能相同。同样,fprintf(stdout,"%s%d\n",s,a)与printf("%s%d\n",s,a)的功能也相同。
前面提到,文件中有一个位置指针,指向当前读/写的位置。文件刚打开时,位置指针指向开始位置或者末尾。利用前面介绍的函数读/写后,位置指针则会往后移动相应长度的距离。也就是说,文件的读/写是顺序往后进行的,但在实际问题中有时需要只读/写文件中某一指定的部分。为此,C语言编译系统提供了移动文件位置指针的函数。9.5文 件 的 定 位9.5.1fseek函数
fseek函数用来移动文件的位置指针,其调用形式为:
fseek(文件指针,位移量,起始点);
其中:“文件指针”指向文件。“位移量”表示移动的字节数,要求位移量是long型数据,以便在文件长度大于64
KB时不会出错。当用常量表示位移量时,要求加后缀“L”。“起始点”表示从何处开始计算位移量,规定的起始点有三种:文件首,当前位置和文件尾。其表示方法如表9-2所示。表9-2起始点的表示例如:
fseek(fp,100L,0);
其意义是把fp所指文件的位置指针移到离文件首100个字节处。
又如:
fseek(fp,
-10L,2);
其意义是将位置指针从文件末尾处向后退(即往文件开始方向)10个字节。
应该注意的是:fseek函数一般用于二进制文件,因为文本文件要发生字符转换,计算位置时往往会发生混乱。
【例9-8】例9-5中,在D盘根目录下的文件student.dat中存储了3个学生的学号、姓名、年龄、班级等信息,编写程序把第2个学生信息显示出来。
源程序如下:
#include<stdio.h>
structstudent
{
intnumber;
charname[10];
intage;
charclass[10];
};
voidmain()
{
FILE*fp;
structstudents;
inti,size;
size=sizeof(structstudent);
if((fp=fopen("D:\\student.dat","rb"))==NULL)
{
printf("Cannotopenthefile!");
exit(0);
}
fseek(fp,size,0);
fread(&s,size,1,fp);
printf("%d%s%d%s\n",s.number,,s.age,s.class);
fclose(fp);
}程序运行结果为:
102zeng19200203
该程序中的fseek(fp,size,0)将文件的位置指针相对于文件开始向后移动一个student结构体的字节数,即移到第2个学生信息的开始位置。9.5.2rewind函数
rewind函数的作用是使位置指针重新返回文件的开头,其调用形式为:
rewind(文件指针);
例如:
rewind(fp);
其意义是将fp所指文件的位置指针重新移到文件开头。
【例9-9
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年度电梯维护保养服务合同9篇
- 2024年度产品生产加工合同的生产数量与质量标准2篇
- 2024中国移动各省招聘易考易错模拟试题(共500题)试卷后附参考答案
- 2024中国电信湖北财务共享服务中心招聘3人易考易错模拟试题(共500题)试卷后附参考答案
- 2024中国电信四川公司校园招聘易考易错模拟试题(共500题)试卷后附参考答案
- 2024年度救灾物资存放搭棚施工合同
- 2024中国人保财险春季招聘易考易错模拟试题(共500题)试卷后附参考答案
- 2024年度物联网应用开发与合作协议3篇
- 2024年度内容创作与传播合作协议
- 2024“才聚齐鲁成就未来”齐鲁(山东)产业投资限公司招聘2人易考易错模拟试题(共500题)试卷后附参考答案
- 第1~4单元期中检测(试题)-2024-2025学年四年级上册数学北师大版
- 《报关单填写规范》课件
- 在线学习管理平台软件开发方案
- 产品研发与创新战略性合作协议书
- 北京邮电大学《计算机网络课程设计》2022-2023学年期末试卷
- 代理记账业务内部规范(三篇)
- 黑龙江大学《应用回归分析》2023-2024学年第一学期期末试卷
- 中层管理干部团队-执行力与领导力提升培训课件
- 2024年保密基础知识竞赛试题库及答案(共350题)
- 招聘笔试题与参考答案(某大型国企)
- 多文本阅读课堂教学实践研究
评论
0/150
提交评论