当前所在位置:珠峰网资料 >> 计算机 >> 软件水平 >> 正文
程序员之程序设计知识点十五
发布时间:2010/6/2 15:33:54 来源:城市学习网 编辑:ziteng
  8.2 文件处理程序结构和文件输入输出常用库函数
  1.正文文件输入处理
  从正文文件逐一输入字符,对输入的字符作某种处理的程序结构有:
  int c; /* 不能为char类型 */
  … /*说明有关变量和设置初值等 */
  fp=fopen(文件名,“r”); /* 正文文件以读方式打开 */
  while(( c= fgetc(f))!= EOF) {
  … /* 这里对刚读人的存于C中的字符作某种处理 */
  }
  fclose(fp);
  .../*输出处理结果 */
  其中函数 fgetC()的说明形式为
  int fgetc(FILE *fp)
  该函数的功能是从与中相联系的文件中读人下一个字符。在文件的控制块中,有一个当前读字符的位置信息,每读入一个字符后,在文件还未结束情况下,这个当前位置信息就移向其后一个字符,从而保证程序反复调用函数fgetc() 能顺序读人文件中的字符。函数fgetc() 的返回值就是读入字符的ASCII代码值。读八字符时,如遇到文件结束,函数返回文件结束标记EOF。对于正文文件,由于字符的ASCII代码不可能是-1,因此可用EOF(定义为-1) 作为文件结束标记。
  【例8.1】 输入正文文件,统计文件中英文字母的个数,并输出。
  为使程序更有一般性,设程序要统计的正文文件名在程序启动时由输入指定。
  # include
  FILE *fp;
  int main()
  { int count, ch;
  char fname[40];
  printf(“输入文件名!\n”);
  scanf(“%s%*c”, fname) ; /* 读入文件名和名后的回车符 */
  if((fp = fopen(fname,“r”))== NULL) { /* 以读方式打开正文文件 */
  printf(“Can not open%s file.\n”, fname);
  return 0; /* 程序非正常结束 */
  }
  count= 0;
  while((ch =fgetc(fp))! =EOF) {
  / * 这里对刚读人的存于ch中的字符信息作某种处理 */
  if(ch>=‘a' && ch<='z' || ch>='A' && ch<='Z' )
  count++;
  }
  fclose(fp);
  /*输出处理结果 */
  printf(“文件%s有英文字母%d个.\n”, fname, count)
  return l; /* 程序执行正常结束 */
  }
  2.二进制文件输入处理
  从二进制文件逐一输入字节,并作某种处理的程序结构有:
  char c; /* 也可以是 int类型 */
  … /* 说明有关变量和设置初值等 */
  fp = fopen(文件名,“rb”);
  while(! feof(fp)) {
  c=fgetc(fp);
  … /* 这里对存于C中的字节信息作某种处理 */
  }
  fclose(fp);
  /* 输出处理结果 */
  其中函数feof() 用来判断文件是否结束。函数调用feof(fp) 用来测试与fp相联系的文件当前状态是否为“文件结束”状态。如果是文件结束状态,函数调用feof(fp)返回非零值,否则返回零值。函数feof()也可用于测试正文文件。
  对于二进制文件,一般不能以读人字节的值是否为-1来判定二进制文件是否结束,而应该用函数feof()。
  3.字符(或字节)逐一生成形成新文件的程序结构
  正文文件与二进制文件的生成程序除文件打开方式不同外,它们的程序结构基本相同。字符(或字节)逐一生成输出,形成新文件的程序结构有:
  int c; /* 也可以是char类型 */
  … /* 说明有关变量和设置初值等 */
  fp = fopen(文件名,“W”); /* 或fP=fopen(文件,“wb”) */
  while(还有字符(或字节)) {
  … /* 生成字符(或字节)存于变量c */
  fpute( c,fp); /* 将生成的字符(或字节)输出 */
  }
  fclose(fp);
  … /* 输出程序结束报告 */
  这里的函数fputc()的说明形式为
  int fputc( char ch, FILE *fp)
  该函数的功能是将ch中的字符输出到与fp文件指针相联系的文件中。函数fputc()返回一个整数值。如果输出成功,则返回值就是输出字符的ASCII代码值;如果输出失败,则返回EOF,即-1。
  曾介绍过的函数putchar()是在stdio.h中用函数fputc()定义的宏:
  # define putchar(c) fputc(c, stdout)
  用宏putchar(c) 比写fputc(c,stdout) 在概念上更简单一些。从使用者来说,可以把putchar(c) 看作函数调用,不必严格地称它为宏调用。
  4. 数据成块输入/输出函数
  为加快程序的处理速度,程序可以成批地读人文件中的数据,也可成批地写数据到文件。它们是函数fread()和fwrite()。
  成批读函数fread()的说明形式为
  int fread(char *buf,int size, int count, FILE *rfp);
  成批写函数fwrite() 的说明形式为
  int fwrite( char *buf, int size, int count,FILE *wfp);
  其中,buf是字符数组首元指针。对fread()来说,它是读人数据的存放开始地址;对bote()来说,是要输出数据的开始地址。size是读写的数据块的字节数。count为要进行读写的数据块的个数。rfp和wfp为文件指针。调用上述函数共读写size。 count个字节或字符。函数fread()和fwrite()的返回值是实际完成输入或输出的数据块的个数。一般情况下,输出调用成功,返回值为count的值。
  如果是读写二进制文件,用函数fread()和fwrite()可以读写任何类型的信息。如有一个如下形式的通信录结构类型:
  typedef struct {
  char name[21]; /* 名字 */
  char phone[15]; /* 电话 */
  char zip[10]; /* 邮编 */
  char addr[31]; /* 地址 */
  } infoType;
  利用类型infoType,可定义数组,如:
  infoType info[30];
  表示结构数组info[]能存放30个通信录数据。而下面的两个函数调用能分别实现20个通信录信息从某文件读出和写入某文件:
  fread( info,sizeof(infoType),20,rfp);
  fwrite( info,sizeo(infoType),20,wfp);
  5.格式输入/输出库函数
  与用函数scanf()从标准设备输入和用函数printf()向标准设备输出一样,一般文件也可进行格式输入和格式输出。
  函数fscanf()和fprintf()分别能对一般文件进行格式输入和格式输出。它们的调用形式分别为
  fscantf(文件指针,格式字符串,输入项地址表)
  和
  fprintf(文件指针,格式字符串,输出项表)
  例如:
  fscanf(rp,“%d%f”,&i,&r);
  fprintf(wp,“i=%d, r=%6.4f\n”, i,r);
  前者表示从与叩相联系的文件为变量i和r读人数据;后者表示将整型变量i和实型变量r的值按格式输出到与呷相联系的文件上。
  6.字符串输入/输出库函数
  函数fgets()和fputs()分别用于从正文文件输入字符串和向正文文件输出字符串。它们的说明形式分别为
  char *fgets(char *str,int n, FILE *fp)
  和
  fputs(char *str, FILE *fp)
  函数fgets() 用于从文件读取字符序列,并存于字符指针所指出的存储区域中。当连续读人n-1个字符,或遇到换行符时,读字符过程结束。
  函数fgets()与函数gets()都在读人的字符序列之后自动存储字符串结束标记'\0’,使其成为字符串,并返回字符率的首字符指针。但它们有差别,函数fgets()除增加整型参数和文件指针参数之外,还在读到换行符时,存储换行符,而函数gets()不存储换行符。
  函数fputs()的作用是将字符串复制到文件。其中字符串的结束标记符是不复制的,也不在复制的字符序列之后另外再添加换行符,这一点与函数puts()不同。
  7.文件定位库函数
  利用前面介绍的函数进行文件操作,只能顺序读写文件。然而,在有些场合,还需要能对文件作随机存取。实际上,因文件是存储在外部存储介质上的数据流,程序即刻能读写的是文件某一位置上的数据,这个位置称为文件的当前读写位置。对于顺序读写情况,每读写一个字符后,当前位置就自动向后移一个字符位置。对于允许随机读写的文件,要读写其他别的位置上的数据,就得改变文件当前读写位置。实现这样的移动可调用库函数rewind()和fseek()来实现。另设有函数ftell()用于查询文件当前读写位置。
  函数rewind()的说明形式为
  void rewind( FILE *fp)
  函数rewind()的作用是使文件当前位置重新回到文件之首。该函数没有返回值。
  函数fseek()是实现文件随机存取的最主要函数,用它可以将文件的当前位置移到文件的任意位置上。所谓文件的随机存取(或随机读写),是指读写完一个字符(或字节)之后,并不一定要读写其后继的字符(或字节),可以改变当前位置,去读写文件中其他位置上的字符(或字节)。
  函数fseek()的说明形式为
  fseek(FILE *fp, long offset, int ptrname)
  其中ptname表示定位基准。只允许0,l或2。其中0代表以文件首为基准,1代表以当前位置为基准,2代表以文件尾为基准。0、l和2分别被定义为名称SEEK-SET、SEEK-CUR和SEEK-END。long型形参offset是偏移量,表示以prname为基准,偏移的字节数。因它是long型形参,当以整数作为它的实参调用函数 fseek()时,直在常数之后加上字母L,表示是long型常量。见下面调用函数fseek()的例子:
  fseek(fp,4OL,SEEK-SET);
  fseek(fp,20L,SEEK-CUR);
  fseek(fp,-30L,SEEK-END);
  分别表示将文件的当前位置定于离文件头4O个字节处、将文件当前位置定于离当前位置20个字节处、将文件的当前位置定于文件尾后退30个字节处。
  函数fseek()一般用于二进制文件的随机读写,这是因为数据在二进制文件中的表示形式与数据在内存中的表示形式相同,各种类型的数据表示都有确定的字节数。而数据在正文文件中的表示形式与数据在内存中的表示形式不同,它们在输入输出时,数据的内外表示形式要进行转换,数值类型的数据在正文文件中的表示没有固定的字节数,计算位置时会发生混乱。
  函数ftell()用于得到文件当前位置相对于文件首的偏移字节数。在随机方式存取文件时,由于文件位置频繁的前后移动,程序不容易确定文件的当前位置。调用函数ftell()就能非常容易地确定文件的当前位置。
  函数ftell()的说明形式为
  long ftell(FILE *fp)
  利用函数ftell()也能方便地知道一个文件的长。如以下语句序列:
  fseek(fp,OL,SEEK-END);
  len=ftell(fp)
  首先将文件的当前位置移到文件的末尾,然后调用函数ftell()获得当前位置相对于文件首的偏移,该偏移值等于文件所含字节数。
  8.文件错误测式库函数
  文件处理程序常用输入输出库函数的返回值来判断输入输出是否发生错误,也可以调用文件错误测试函数了解刚完成的文件输入输出函数的调用是否有错。文件错误测试函数的说明形式为
  int ferror(FILE *fp)
  函数的返回值是与文件指针中相联的最近一次文件库函数调用是否发生错误。若有错,函数返回非0值,若没有错误,函数返回0值。通常在这非0值,详细指出错误的类别和原因。
广告合作:400-664-0084 全国热线:400-664-0084
Copyright 2010 - 2017 www.my8848.com 珠峰网 粤ICP备15066211号
珠峰网 版权所有 All Rights Reserved