C语言文件操作

9 篇文章 0 订阅
6 篇文章 0 订阅

一、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 打开只读文件,该文件必须存在。
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>中定义的以下常量之一指定专门用作此函数的参数:

ConstantReference position
SEEK_SETBeginning of file
SEEK_CURCurrent position of the file pointer
SEEK_ENDEnd 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 sample
14.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
该示例打开myfile.txt,然后读取第一个字符,然后读取相同的第二个字符3次。

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值