C语言标准I/O文件操作


1.fopen()函数

           这一函数在stdio.h中声明,它的第一个参数是要打开的文件名,更确切的说,是包含该文件名的字符串的地址。第二个参数是用于指定文件打开模式的一个字符串。C库提供了一些可能的模式如下:

模式字符串

意义

“r”

打开一个文本文件,可以读取文件

“w”

打开一个文本文件,可以写入文件,先将文件的长度截为0,如果文件不存在则创建之

“a”

打开一个文本文件可以写入文件,向已有文件的尾部追加内容,如果该文件不存在则创建之

“r+”

打开一个文本文件,可以进行更新,也即可以读取和写入文件

“w+”

打开一个文本文件,可以进行更新(读取和写入),如果该文件存在则首先长度截为0,若不存在则创建之

“a+”

打开一个文本文件,可以进行更新(读取和写入),向已有文件的尾部追加内容,如果文件不存在则创建之,可以读取整个文件,但写入时只能追加内容

“rb”,”wb”,”ab”

“ab+”,”a+b”,”wb+”

“w+b”,”ab+”,”a+b”

与前面的模式相似,只是使用二进制模式而非文本模式打开文件

Eg :FILE *fp;

char *filepath;

fp = fopen(filepath,”r”);

注意:如果使用任何一种w模式打开一个已有的文件,文件的内容将被删除,以便程序一个空文件开始操作。

程序成功打开一个文件后,fopen函数返回一个文件指针,其他io函数用这个指针来指定该文件。文件指针(fp)是一种指向FILE的指针。FILE定义在stdio.h中,指针fp并不指向实际的文件,而是指向一个关于文件的信息的数据包。

typedef struct _iobuf

{

      char*   _ptr;//文件输入的下一个位置

      int _cnt;//当前缓冲区的相对位置

      char*   _base;//基址,即文件的起始位置

      int _flag;//文件标志

      int _file;//文件的有效性验证

      int _charbuf;//检查缓冲区的状况,如果无缓冲区则不读取

      int _bufsiz;//文件的大小

      char*   _tmpfname;//临时文件名

} FILE;

如果不能打开文件,fopen返回的是一个空指针

ch = getc(fp)//从fp指针指定的文件中获得一个字符

putc(ch,fpout)//把ch写入FILE指针fpout指定的文件中。

如果在尝试读入字符时发现已经到达文件结尾,getc函数会返回一个特殊值EOF,所以C语言只有在读取超出文件结尾以后才会发现文件的结尾,为了避免试图读取空文件带来的问题,应该对文件的输入使用入口条件循环(而非do while循环)。鉴于getc函数的设计,程序应该在进入循环体之前尝试进行第一次读取。所以下面是一个比较好的模式:

char  ch;

while((ch = getc(fp)) != EOF) {…}

 2.fclose()函数

           fclose(fp)函数关闭由指针fp指定的文件,同时根据需要刷新缓冲区。更正规的程序也行还要检查是否成功关闭了文件,如果成功关闭,返回0,否则返回EOF。(磁盘已满,磁盘被移走或者出现io错误等都会导致fclose执行失败)。

fscanf 和fprintf函数与scanf和printf的工作方式类似。

FILE *fp;

fp = fopen(filename,’a+’);

fprintf(fp,”%s”,word);//向fp指向的文件写入word指向的字符串

fscanf(fp,”%s”,word);//从fp指向的文件读取字符串到word中

rewind(fp)//回到文件的开始处。

3.fseek() 和ftell().

           fseek的3个参数中,第一个参数是指向被搜索文件的FILE指针,应该已经使用fopen打开了该文件

第二个参数称为偏移量,表示从起点开始要移动的距离,这个参数必须是一个long类型的值,可以为正(前移)负(后移),一可以为零。

第三个参数是模式,用来标识起点。在ANSI下,stdio.h头文件指定了下列模式常量:

SEEK_SET:文件的开始

SEEK_CUR:当前位置

SEEK_END:文件的结尾

eg:

fseek(fp,0L,SEEK_SET)//找到文件的开始处,等价与rewind(fp)

fseek(fp,10L,SEEK_SET)//找到文件的第10个字节

fseek(fp,2L,SEEK_CUR)//从当前位置向前移动2个字节

fseek(fp,-10L,SEEK_END)//从文件结尾处退回10个字节

如果一切正常,fseek返回值为0,如果有错误出现,例如试图移动超出文件范围,fseek返回值为-1.

ftell为long类型,它返回当前文件的位置。ftell函数通过返回距离文件开始处字节数目来确定文件的位置。文件的第一个字节到文件开始处的距离是字节0,依次类推。在ANSI C下,这种定义适用于以二进制模式打开的文件,但是对于以文本模式打开的文件来讲,不一定是这样。

4.二进制IO:fread() 和fwrite()

           fwrite的原型是:

size_t  fwrite(const  void *restrict  ptr,  size_t  size, size_t  nmemb,  FILE * restrict fp);

fwrite()函数将二进制数据写入文件,指针ptr是要写入的数据块的地址,size表示要写入的数据块的大小,以字节为单位,nmemb表示数据块的数目,fp指定要写入的文件。例如要保存一个256字节大小的数据对象(比如数组)可以这样写:

char buffer[256];

fwrite(buffer,256,1,fp);

这一调用将一块256字节的数据块从缓冲区写入了文件。又比如要保存一个包含10个double值的数组可以这样做:

double  earnings[10];

fwrite(earnings,sizeoof(double),10,fp);

fwirte会返回成功写入的项目数,正常情况下他与nmemb相等,如果有写入错误的话,返回值就会小于nmemb。

 

fread()的原型为

size_t fread(void  *restrict  ptr, size_t  size,  size_t nmemb,  FILE *restrict fp);

fread()与fwrite()函数的参数相同,ptr为读入文件数据的内存存储地址,fp指定要读取的文件,使用这一函数来读取通过fwrite函数写入的数据,例如要恢复前一例子中保存的10个double值的数组可以如下调用:

double earnings[10];

fread(earnings,sizeof(double),10,fp);

fread会返回成功读取的项目数,正常情况下他与nmemb相等,如果有读取错误的话,返回值就会小于nmemb。

 

当标准输入函数返回EOF时通常表示已经达到了文件结尾,可是这也有可能表示发生了读取错误,使用feof()和ferror()可以区分这两种情况,如果最近一次输入输出调用检测到文件的结尾,feof返回一个非零值,否则返回零。如果发生读写错误,ferror返回一个非零值,否则返回一个零。

 

 

posted @ 2012-11-06 14:32  JWMNEU  阅读(476)  评论(0编辑  收藏  举报