一、C文件概述
1、“文件(file)”:所谓“文件”是指一组相关数据的有序集合。数据以文件的形式存放在
外部介质(一般是磁盘、磁带、光盘等)上,在操作系统中是以文件为单位对数据进行管理的。以文件名作为访问文件的标识。
2、C语言把文件看作一个字节序列,即由一连串的字节组成。根据文件中的数据组织形式,数据文件可分为ASCII码文件和二进制文件。
ASCII码文件,又称为“文本文件”(text),其每一个字节存放一个ASCII码。
二进制文件,把内存中的数据按其在内存中的存储形式存放在磁盘上。
例:十进制整数10000,在内存中占两个字节,其存放形式是:00100111,00010000。在二进制文件中也按这种方式存放。
但是,在ASCII文件中,十进制整数10000存放为31H、30H、30H、30H、30H,占五个字节,它们分别是1、0、0、0、0、0字母的ASCII码。
3、按照操作系统对磁盘文件的读写方式,文件可以分为“缓冲文件系统”和“非缓冲文件系统”。
缓冲文件系统:操作系统在内存中为每一个正在使用的文件开辟一个读写缓冲区。从内存向磁盘输出数据必须先送到内存中的缓冲区,
装满缓冲区后才一起送到磁盘上。如果从磁盘向内存读入数据,则一次从磁盘文件将一批数据输入到内存缓冲区,然后再从缓冲区逐个地将数据送到程序数据区。
非缓冲文件系统:指操作系统不自动开辟确定大小的读写缓冲区,而由程序为每个文件设定缓冲区。
在UNIX系统下,用缓冲文件系统来处理文本文件,用非缓冲文件系统处理二进制文件。ANSI C标准只采用缓冲文件系统。
在C语言中,没有输入输出语句,对文件的读写都是用库函数来实现的。本章只介绍ANSI C标准规定的缓冲文件系统。
二、文件类型指针
缓冲文件系统中,每一个使用的文件都在内存中开辟一个“文件信息区”,用来存放文件的相关信息
(文件的名字、文件当前的读写位置、文件操作方式等)。这些信息保存在一个结构体变量中,
该结构体是由系统定义的,取名为FILE。Turbo C 3.0 在stdio.h文件中有以下文件类型的声明:
typedef struct {
int level; /* 缓冲区“满”或“空”的程度 */
unsigned flags; /* 文件状态标志 */
char fd; /* 文件描述符*/
unsigned char hold; /* 如无缓冲区不读取字符 */
int bsize; /* 缓冲区的大小 */
unsigned char *buffer; /* 数据缓冲区的位置*/
unsigned char *curp; /* 指针,当前的指向 */
unsigned istemp; /* 临时文件,指示器 */
short token; /* 用于有效性检查 */
} FILE;
定义文件指针变量的一般形式为:
FILE *文件结构指针变量名
例如:FILE *fp;
注意:只有通过文件指针,才能调用相应的文件。
三、文件操作函数
1.fopen
FILE * fopen ( const char * filename, const char * mode );
描述:
Open file
打开在参数filename中指定的文件,返回与该文件关联的指针。
流中允许的操作以及这些操作的执行方式由mode参数定义。
如果已知不指向交互式设备,则返回的流将默认被完全缓冲。
通过调用fclose或freopen可以将返回的指针从文件中解除关联。
所有打开的文件在正常程序终止时自动关闭。
运行环境至少支持同时打开的FOPEN_MAX文件。
参数:
filename
C字符串,包含要打开的文件的名称。
其值应遵循运行环境的文件名称规范,并且可以包含路径(如果系统支持)。
mode
包含文件访问模式的C字符串。
mode如下:
使用文件方式 | 含义 |
"r"(只读) | 为输入打开一个文本文件 |
"w"(只写) | 为输出打开一个文本文件 |
"a"(追加) | 为追加打开一个文本文件 |
"rb"(只读) | 为输入打开一个二进制文件 |
"wb"(只写) | 为输出打开一个二进制文件 |
"ab"(追加) | 为追加打开一个二进制文件 |
"r+"(读写) | 为读/写打开一个文本文件 |
"w+"(读写) | 为读/写创建一个文本文件 |
"a+"(读写) | 为读/写打开一个文本文件 |
"rb+"(读写) | 为读/写打开一个二进制文件 |
"wb+"(读写) | 为读/写创建一个二进制文件 |
"ab+"(读写) | 为读/写打开一个二进制文件 |
r+ 打开可读写的文件,该文件必须存在。
w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。
a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。
上述的形态字符串都可以再加一个b字符,如rb、w+b或ab+等组合,加入b 字符用来告诉函数库打开的文件为二进制文件,而非纯文字文件。
不过在POSIX系统,包含Linux都会忽略该字符。由fopen()所建立的新文件会具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)权限,此文件权限也会参考umask值。
返回值,文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno 中。
附加说明,一般而言,打开文件后会作一些文件读取或写入的动作,如果打开文件失败,接下来的读写动作也无法顺利进行,所以在fopen()后请作错误判断及处理。
返回值:
如果文件成功打开,该函数将返回一个指向FILE对象的指针,该指针可用于标识将来操作的流。
否则,返回一个空指针。
在大多数库实现中,errno变量在失败时也被设置为系统特定的错误代码。
/* fopen example */
#include <stdio.h>
int main ()
{
FILE * pFile;
pFile = fopen ("myfile.txt","w");
if (pFile!=NULL)
{
fputs ("fopen example",pFile);
fclose (pFile);
}
return 0;
}
2.fclose
int fclose ( FILE * stream );描述:
Close file
关闭与流关联的文件并将其解除关联。
与流关联的所有内部缓冲区与其关联并刷新:写入任何未写入输出缓冲区的内容,并丢弃任何未读输入缓冲区的内容。
即使调用失败,作为参数传递的流将不再与文件或缓冲区关联。
参数:
指向指定要关闭的流的FILE对象的指针。
返回值:
如果流成功关闭,则返回零值。
失败时,返回EOF。
/* fclose example */
#include <stdio.h>
int main ()
{
FILE * pFile;
pFile = fopen ("myfile.txt","w+");
fprintf (pFile, "fclose example");
fclose (pFile);
return 0;
}
这个简单的代码创建一个新的文本文件,然后写一个句子,然后关闭它。
3.fflush
int fflush ( FILE * stream );描述:
Flush stream
fflush是一个计算机函数,功能是冲洗流中的信息,该函数通常用于处理磁盘文件。fflush()会强迫将缓冲区内的数据写回参数stream 指定的文件中。如果给定的流是打开写入的(或者如果打开了更新并且最后一个I / O操作是输出操作),则其输出缓冲区中的任何未写入数据将被写入该文件。
如果stream是一个空指针,那么所有这些流都被刷新。
在所有其他情况下,行为取决于特定的库实现。 在某些实现中,刷新一个打开的数据流会导致其输入缓冲区被清除(但这不是可移植的预期行为)。
此调用后,该流保持打开状态。
当一个文件被关闭时,无论是因为调用fclose还是因为程序终止,所有与其关联的缓冲区都会自动刷新。
参数:
stream
指向指定缓冲流的FILE对象的指针。
返回值:
零值表示成功。
如果发生错误,则返回EOF并设置错误指示符
在打开更新文件(即打开读取和写入)的文件中,在执行输入操作之前,应在输出操作之后清除流。 这可以通过重新定位(fseek,fsetpos,rewind)来完成,也可以通过显式调用fflush来完成,如下例所示:
/* fflush example */
#include <stdio.h>
char mybuffer[80];
int main()
{
FILE * pFile;
pFile = fopen ("example.txt","r+");
if (pFile == NULL) perror ("Error opening file");
else {
fputs ("test",pFile);
fflush (pFile); // flushing or repositioning required
fgets (mybuffer,80,pFile);
puts (mybuffer);
fclose (pFile);
return 0;
}
}
4.fputs
int fputs ( const char * str, FILE * stream );
描述:
Write string to stream
将str指向的C字符串写入流。
该函数从指定的地址(str)开始复制,直到达到终止空字符('\ 0')。 这个终止的空字符不会被复制到流中。
请注意,fputs不仅与put不同,可以指定目标流,而且fputs不会写入其他字符,put会自动在末尾附加换行符。
参数:
str
写入流的C字符串
stream
指向标识输出流的FILE对象的指针。
返回值:
成功时,返回一个非负值。
出错时,函数返回EOF并设置错误指示符(ferror)。
/* fputs example */
#include <stdio.h>
int main ()
{
FILE * pFile;
char sentence [256];
printf ("Enter sentence to append: ");
fgets (sentence,256,stdin);
pFile = fopen ("mylog.txt","a");
fputs (sentence,pFile);
fclose (pFile);
return 0;
}
该程序允许在每次运行时将一行添加到名为mylog.txt的文件中。
5.fgets
char * fgets ( char * str, int num, FILE * stream );
描述:
Get string from stream
从流中读取字符,并将它们作为C字符串存储到str中,直到(num-1)个字符被读取,或者到达换行符或文件结束,以先发生者为准。
一个换行符使fgets停止读取,但是它被认为是一个有效的字符,并被包含在str中的字符串复制到str中。
在将字符复制到str之后,会自动附加一个终止空字符。
请注意,fgets与gets完全不同:不仅fgets接受流参数,还允许指定str的最大大小,并在字符串中包含任何结束换行符。
参数:
str
指向复制字符串读取的字符数组的指针。
num
要复制到str的最大字符数(包括终止的空字符)。
stream
指向标识输入流的FILE对象的指针。
标准输入可以被用作从标准输入中读取的参数。
返回值:
成功时,函数返回str。
如果在尝试读取一个字符时遇到文件结束,则设置eof指示符(feof)。 如果在任何字符被读取之前发生这种情况,则返回的指针是一个空指针(str的内容保持不变)。
如果发生读错误,则会设置错误指示符(ferror)并返回一个空指针(但str指向的内容可能已经更改)。
/* fgets example */
#include <stdio.h>
int main()
{
FILE * pFile;
char mystring [100];
pFile = fopen ("myfile.txt" , "r");
if (pFile == NULL) perror ("Error opening file");
else {
if ( fgets (mystring , 100 , pFile) != NULL )
puts (mystring);
fclose (pFile);
}
return 0;
}
本示例读取myfile.txt的第一行或前99个字符(以先到者为准),并将其打印在屏幕上。
6.fgetc
int fgetc ( FILE * stream );
描述:
Get character from stream
返回指定流的内部文件位置指示符当前指向的字符。 内部文件位置指示符然后被提前到下一个字符。
如果流在被调用时位于文件结尾,则该函数返回EOF并为流(feof)设置文件结束指示符。
如果发生读取错误,函数返回EOF并设置流的错误指示符(ferror)。
除了可以在某些库中将getc实现为宏之外,fgetc和getc是等价的。
参数:
stream
指向标识输入流的FILE对象的指针。
返回值:
成功时,返回字符(提升为int值)。
返回类型是int以适应特殊值EOF,这表示失败:
如果位置指示符位于文件末尾,则函数返回EOF并设置流的eof指示符(feof)。
如果发生其他读取错误,该函数也会返回EOF,但会设置其错误指示符(ferror)。
/* fgetc example: money counter */
#include <stdio.h>
int main ()
{
FILE * pFile;
int c;
int n = 0;
pFile=fopen ("myfile.txt","r");
if (pFile==NULL) perror ("Error opening file");
else
{
do {
c = fgetc (pFile);
if (c == '$') n++;
} while (c != EOF);
fclose (pFile);
printf ("The file contains %d dollar sign characters ($).\n",n);
}
return 0;
}
该程序逐字符读取一个名为myfile.txt的现有文件,并使用n变量来计算该文件包含多少美元字符($)。
7.fputc
int fputc ( int character, FILE * stream );
描述:
Write character to stream
将一个字符写入流,并推进位置指示器。
该字符被写入流的内部位置指示器所指示的位置,然后自动前进一个。
参数:
character
写入时,该值在内部转换为无符号字符。
stream
指向标识输出流的FILE对象的指针。
返回值:
成功后,返回写入的字符。
如果发生写入错误,则返回EOF并设置错误指示符(ferror)。
/* fputc example: alphabet writer */
#include <stdio.h>
int main ()
{
FILE * pFile;
char c;
pFile = fopen ("alphabet.txt","w");
if (pFile!=NULL) {
for (c = 'A' ; c <= 'Z' ; c++)
fputc ( c , pFile );
fclose (pFile);
}
return 0;
}
这个程序创建一个名为alphabet.txt的文件,并将ABCDEFGHIJKLMNOPQRSTUVWXYZ写入它。
8.fwrite
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
描述:
Write block of data to stream
从ptr指向的内存块到流中的当前位置写入一个count元素的数组,每个元素的大小为size个字节。
流的位置指示符通过被写入的总字节数提前。
在内部,该函数将ptr指向的块解释为它是一个unsigned char类型的(size * count)元素的数组,并将它们顺序写入流,就像为每个字节调用fputc一样
参数:
ptr
指向要写入的元素数组的指针,转换为const void *。
size
每个要写入的元素的字节大小。
size_t是一个无符号整数类型。
count
元素的数量,每个元素的大小为字节。
size_t是一个无符号整数类型。
stream
指向指定输出流的FILE对象的指针。
返回值:
返回成功写入的元素的总数。
如果此编号与计数参数不同,写入错误将导致功能无法完成。 在这种情况下,将为流设置错误指示符(ferror)。
如果大小或计数为零,则函数返回零并且错误指示符保持不变。
size_t是一个无符号整数类型。
/* fwrite example : write buffer */
#include <stdio.h>
int main ()
{
FILE * pFile;
char buffer[] = { 'x' , 'y' , 'z' };
pFile = fopen ("myfile.bin", "wb");
fwrite (buffer , sizeof(char), sizeof(buffer), pFile);
fclose (pFile);
return 0;
}
创建一个名为myfile.bin的文件,并将缓冲区的内容存储到该文件中。 为了简单起见,缓冲区包含char元素,但可以包含任何其他类型。
sizeof(buffer)是数组的长度(以字节为单位),因为数组有三个元素,每个元素都是一个字节。
9.fread
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
描述:
Read block of data from stream
从流中读取count个元素的数组,每个元素的大小为字节,并将其存储在由ptr指定的内存块中。
流的位置指示符超前读取的总字节数。
如果成功读取,则总字节数是(size * count)。
参数:
ptr
指向至少(size * count)字节大小的内存块,转换为void *。
size
每个要读取的元素的大小(以字节为单位)。
size_t是一个无符号整数类型。
count
元素的数量,每个元素的大小为字节。
size_t是一个无符号整数类型。
stream
指向指定输入流的FILE对象的指针。
返回值:
返回成功读取的元素总数。
如果此编号与计数参数不同,则发生读取错误或读取时达到文件结束。 在这两种情况下,都设置了适当的指标,可以分别用ferror和feof来检查。
如果大小或计数为零,则函数返回零,并且流状态和ptr指向的内容都保持不变。
size_t是一个无符号整数类型。
/* fread example: read an entire file */
#include <stdio.h>
#include <stdlib.h>
int main () {
FILE * pFile;
long lSize;
char * buffer;
size_t result;
pFile = fopen ( "myfile.bin" , "rb" );
if (pFile==NULL) {fputs ("File error",stderr); exit (1);}
// obtain file size:
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
buffer = (char*) malloc (sizeof(char)*lSize);
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}
// copy the file into the buffer:
result = fread (buffer,1,lSize,pFile);
if (result != lSize) {fputs ("Reading error",stderr); exit (3);}
/* the whole file is now loaded in the memory buffer. */
// terminate
fclose (pFile);
free (buffer);
return 0;
}
该代码将myfile.bin加载到一个动态分配的内存缓冲区中,该缓冲区可用于将文件内容作为一个数组来操作。
10.fseek
int fseek ( FILE * stream, long int offset, int origin );
描述:
Reposition stream position indicator
重新定位流位置指示器
将与流相关的位置指示器设置为新的位置。
对于以二进制模式打开的流,通过将偏移量添加到由原点指定的参考位置来定义新的位置。
对于以文本模式打开的流,偏移量应为零或先前调用ftell返回的值,并且源必须是SEEK_SET。
如果使用这些参数的其他值调用函数,则支持取决于特定的系统和库实现(非便携式)。
成功调用此函数后,流的文件结束内部指示符将被清除,并且以前调用此流上ungetc的所有效果都将被删除。
在打开更新(读取+写入)的流上,调用fseek允许在读取和写入之间切换。
参数:
stream
指向标识流的FILE对象的指针。
offset
二进制文件:从原点偏移的字节数。
文本文件:可以是零,也可以是由ftell返回的值。
origin
用作偏移参考的位置。 它由<cstdio>中定义的以下常量之一指定专门用作此函数的参数:
Constant | Reference position |
---|---|
SEEK_SET | Beginning of file |
SEEK_CUR | Current position of the file pointer |
SEEK_END | End of file * |
SEEK_SET:从文件头
SEEK_CUR:从文件当前位置
SEEK_END:从文件结尾
*库实现允许不能有效地支持SEEK_END(因此,使用它的代码没有真正的标准可移植性)。
返回值:
如果成功,该函数返回零。
否则,它返回非零值。
如果发生读取或写入错误,则设置错误指示符(ferror)。
/* fseek example */
#include <stdio.h>
int main ()
{
FILE * pFile;
pFile = fopen ( "example.txt" , "wb" );
fputs ( "This is an apple." , pFile );
fseek ( pFile , 9 , SEEK_SET );
fputs ( " sam" , pFile );
fclose ( pFile );
return 0;
}
该代码成功执行后,文件example.txt包含:
This is asampple.
11.ftell
long int ftell ( FILE * stream );
描述:
Get current position in stream
获取流中的当前位置
返回流的位置指示符的当前值。
对于二进制流,这是从文件开始的字节数。
对于文本流,数值可能没有意义,但仍然可以使用fseek将位置恢复到相同的位置(如果有使用ungetc的字符仍待读取,则行为未定义)。
参数:
stream
指向标识流的FILE对象的指针。
返回值:
成功时,位置指示器的当前值被返回。
失败时,返回-1L,并将errno设置为系统特定的正值。
/* ftell example : getting size of a file */
#include <stdio.h>
int main ()
{
FILE * pFile;
long size;
pFile = fopen ("myfile.txt","rb");
if (pFile==NULL) perror ("Error opening file");
else
{
fseek (pFile, 0, SEEK_END); // non-portable
size=ftell (pFile);
fclose (pFile);
printf ("Size of myfile.txt: %ld bytes.\n",size);
}
return 0;
}
这个程序打印出myfile.txt的大小(以字节为单位)。
12.freopen
FILE * freopen ( const char * filename, const char * mode, FILE * stream );
描述:
Reopen stream with different file or mode
用不同的文件或模式重新打开流
重复使用流,以打开由文件名指定的文件或更改其访问模式。
如果指定了新文件名,函数首先尝试关闭任何已经与流关联的文件(第三个参数)并将其解除关联。 然后,不管流是否成功关闭,freopen打开由filename指定的文件,并将其与流关联,就像fopen使用指定的模式一样。
如果文件名是一个空指针,函数将尝试改变流的模式。 虽然允许特定的库实现来限制允许的更改,以及在哪些情况下。
错误指示器和eof指示器会自动清除(就像调用清零器一样)。
这个函数对于将stdin,stdout和stderr等预定义的流重定向到特定的文件(参见下面的例子)特别有用。
参数:
filename
C字符串,包含要打开的文件的名称。
其值应遵循运行环境的文件名称规范,并且可以包含路径(如果系统支持)。
如果此参数是空指针,则该函数会尝试更改流的模式,就好像当前与该流关联的文件名已被使用。
mode
包含文件访问模式的C字符串。
stream
指向标识要重新打开的流的FILE对象的指针。
返回值:
如果文件被成功重新打开,该函数将返回作为参数流传递的指针,该指针可用于识别重新打开的流。
否则,返回一个空指针。
在大多数库实现中,errno变量在失败时也被设置为系统特定的错误代码。
/* freopen example: redirecting stdout */
#include <stdio.h>
int main ()
{
freopen ("myfile.txt","w",stdout);
printf ("This sentence is redirected to a file.");
fclose (stdout);
return 0;
}
此示例代码将通常转到标准输出的输出重定向到一个名为myfile.txt的文件,在执行该程序后包含:
This sentence is redirected to a file. |
13.fsetpos
int fsetpos ( FILE * stream, const fpos_t * pos );
描述:
Set position indicator of stream
设置流的位置指示符
恢复流中的当前位置。
与流相关的内部文件位置指示符被设置为由pos表示的位置,该位置是指向fpos_t对象的指针,其值通过调用fgetpos而预先获得。
成功调用此函数后,流的文件结束内部指示符将被清除,并且以前调用此流上ungetc的所有效果都将被删除。
在打开更新(读取+写入)的流上,调用fsetpos允许在读取和写入之间切换。
类似的函数fseek可以用来设置以二进制模式打开的流中的任意位置。
参数:
stream
指向标识流的FILE对象的指针。
pos
指向一个fpos_t对象的指针,该对象包含之前通过fgetpos获取的位置
返回值:
如果成功,该函数返回零。
失败时,将返回一个非零值,并将errno设置为系统特定的正值。
/* fsetpos example */
#include <stdio.h>
int main ()
{
FILE * pFile;
fpos_t position;
pFile = fopen ("myfile.txt","w");
fgetpos (pFile, &position);
fputs ("That is a sample",pFile);
fsetpos (pFile, &position);
fputs ("This",pFile);
fclose (pFile);
return 0;
}
这段代码成功执行后,名为myfile.txt的文件将包含:
This is a sample14.fgetpos
int fgetpos ( FILE * stream, fpos_t * pos );
描述:
Get current position in stream
获取流中的当前位置
检索流中的当前位置。
该函数使用pos指向的fpos_t对象来填充流位置指示器所需的信息,以便通过调用fsetpos将流恢复到当前位置(以及多字节状态,如果面向广泛的话)。
ftell函数可以用来以整数值的形式检索流中的当前位置。
参数:
stream
指向标识流的FILE对象的指针。
pos
指向fpos_t对象的指针。
这应该指向一个已经分配的对象。
返回值:
成功时,函数返回零。
如果发生错误,则将errno设置为特定于平台的正值,并返回一个非零值。
/* fgetpos example */
#include <stdio.h>
int main ()
{
FILE * pFile;
int c;
int n;
fpos_t pos;
pFile = fopen ("myfile.txt","r");
if (pFile==NULL) perror ("Error opening file");
else
{
c = fgetc (pFile);
printf ("1st character is %c\n",c);
fgetpos (pFile,&pos);
for (n=0;n<3;n++)
{
fsetpos (pFile,&pos);
c = fgetc (pFile);
printf ("2nd character is %c\n",c);
}
fclose (pFile);
}
return 0;
}
可能的输出(使用包含ABC的myfile.txt):
1st character is A 2nd character is B 2nd character is B 2nd character is B |
15.feof
int feof ( FILE * stream );
描述:
Check end-of-file indicator
检查文件结束指示符
检查是否设置了与流关联的文件结束指示符,如果是,则返回一个不同于零的值。
这个指标通常是由试图在文件末尾读取的数据流的先前操作设置的。
请注意,流的内部位置指示器可能指向下一个操作的文件结束,但仍然可能不会设置文件结束指示符,直到操作尝试读取该点为止。
通过调用fseek,fsetpos或freopen来清除该指标。 尽管如果位置指示器没有被这样的调用重新定位,那么下一个I / O操作可能再次设置指示器。
参数:
stream
指向标识流的FILE对象的指针。
返回值:
如果设置了与流关联的文件结尾指示符,则返回非零值。
否则,返回零。
/* feof example: byte counter */
#include <stdio.h>
int main ()
{
FILE * pFile;
int n = 0;
pFile = fopen ("myfile.txt","rb");
if (pFile==NULL) perror ("Error opening file");
else
{
while (fgetc(pFile) != EOF) {
++n;
}
if (feof(pFile)) {
puts ("End-of-File reached.");
printf ("Total number of bytes read: %d\n", n);
}
else puts ("End-of-File was not reached.");
fclose (pFile);
}
return 0;
}
此代码打开名为myfile.txt的文件,并通过逐个读取所有文件来计算它包含的字符数。 程序检查是否到达文件结尾,如果是,则打印读取的总字节数。
16.ferror
int ferror ( FILE * stream );
描述:
Check error indicator
检查错误指示器
检查是否设置了与流关联的错误指示符,如果是,则返回一个不同于零的值。
这个指标通常是由失败的流上的一个前面的操作设置的,并且通过调用 clearerr, rewind or freopen来清除。
参数:
stream
指向标识流的FILE对象的指针。
返回值:
如果设置了与流关联的错误指示符,则返回非零值。
否则,返回零。
/* ferror example: writing error */
#include <stdio.h>
int main ()
{
FILE * pFile;
pFile=fopen("myfile.txt","r");
if (pFile==NULL) perror ("Error opening file");
else {
fputc ('x',pFile);
if (ferror (pFile))
printf ("Error Writing to myfile.txt\n");
fclose (pFile);
}
return 0;
}
该程序以只读模式打开一个名为myfile.txt的现有文件,但试图向其中写入一个字符,生成一个由ferror检测到的错误。
输出:
Error Writing to myfile.txt