为了账号安全,请及时绑定邮箱和手机立即绑定

读写数据块函数fread怎么用?

读写数据块函数fread怎么用?

SSM
浮云间 2019-02-20 10:15:11
本人照题目设计了个程序,想用fread读取数据,结果......题目是:某班有30名学习,每名学生的数据包括学号、姓名、3门课的成绩,输入20名学生的数据,要求打印出3门课总平均成绩,以及总分最高的学生的数据(包括学号、姓名、3门课成绩,平均成绩)。
查看完整描述

3 回答

?
达令说

TA贡献1821条经验 获得超6个赞

fread(&stu[i],sizeof(struct student),1,fp);
二进制读取,每次读取指定字节数
你的文件是文本方式的,读出来就错了

float score[3];//float类型是4个byte,score[3]就是12个byte

比如----------------------------------------------------
200501 zhao 78 79 79
结构中定义num是long型,占4个字节
这里200501是字符型,占6个字节

用fread()读,num就对应"2005"(存储为32 30 30 35)

可以用Ultra-edit查看文本文件的二进制

查看完整回答
反对 回复 2019-03-26
?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

首先是最简单的读写一个字符的函数fputc和fgetc,在这个基础上又出现了putw和getw、fgets和fputs,此外还说过格式化读写函数fprintf和fscanf函数

  从原理上来说,只要fputc和fgetc函数基本就可以完成数据的读写操作了,但是在实际的使用中会遇到诸多不便,因此上面那一大堆函数就冒出来了(其实也不多)。上面函数中最方便的就是格式化读写函数fprintf和fscanf了,因为可以一行行的进行读取,但是有个问题就是这两位老人家动作比较慢,fprintf在写文件的时候要把二进制形式表示的数据转换为ASCII码形式,fscanf在读文件的时候又要将ASCII码转换为二进制的形式。

  好不容易出来个好用的函数,竟然是个慢性子,聪明的你现在也许就在想了:那能不能不转换,直接读写二进制的数据呢?答案就是fread和fwrite,在需要频繁进行数据读写的时候,使用这两个函数将大大提升效率。

  fread和fwrite函数的定义

  fread(pBuffer,size,count,pFile);

  fwrite(pBuffer,size,count,pFile);

  要读写一个数据块的话,无论是读还是写,都需要指定一个起始地址,读的话从这个起始地址读,写的话从这个起始地址写,上面函数定义中的第一个参数pBuffer就是用于指定这个起始地址,size读写的字节数,count则指定读写多少个size大小的数据,pFile是文件结构指针。

  fread和fwrite函数使用示例

  说到数据块我们自然会想到结构体,如果一个文件中保存的是一个个结构体信息,那每一个结构体信息就可以看做一个数据块了。这里直接用前面文章中我们一直使用的学生成绩信息的结构体:

  C语言: 知蚁博客

  struct student

  {

  int nID; //学号

  char chName[20]; //姓名

  float fScores[3]; //3门课的成绩

  };

  实例程序有点小复杂的,首先我们自己新建一个txt文件,也就是ASCII文件啦,然后写上一些数据,如下:

  1 zhangsan 78.0 79.0 80.0

  2 lisi 79.0 77.0 78.0

  3 wangwu 90.0 97.0 78.0

  4 zhaokai 56.0 57.0 58.0

  我们先用ASCII方式打开这个文件,通过fscanf函数读取里面的数据,然后通过fwrite写入到新的二进制格式的文件中,这样我们就得到了一个保存上面信息的二进制格式的文件了,下面就是通过fread函数进行数据的读取了。(记住:fread和fwrite一般用于二进制文件的输入输出,ASCII文件还是不要考虑了)。

  C++语言: 知蚁博客

  #include "stdio.h"

  struct student

  {

  int nID; //学号

  char chName[20]; //姓名

  float fScores[3]; //3门课的成绩

  };

  void main()

  {

  FILE *pRead,*pWrite;

  struct student tStu[4];

  struct student *ptStu = NULL;

  int nCount = 0;

  //ASCII方式打开文件 用于读入

  pRead=fopen("stu_scores.txt","r");

  if(NULL == pRead)

  {

  return;

  }

  //二进制文件打开文件 用于写入

  pWrite=fopen("stu_scores_bin.txt","wb");

  if(NULL == pWrite)

  {

  fclose(pRead);

  return;

  }

  //fscanf读取数据,fwrite写入数据

  ptStu = tStu;

  while(!feof(pRead))

  {

  fscanf(pRead,"%d %s %f %f %f\n",&ptStu->nID,ptStu->chName,&ptStu->fScores[0],&ptStu->fScores[1],&ptStu->fScores[2]);

  fwrite(ptStu,sizeof(struct student),1,pWrite);

  printf("%d %s %.1f %.1f %.1f\n",ptStu->nID,ptStu->chName,ptStu->fScores[0],ptStu->fScores[1],ptStu->fScores[2]);

  ptStu++;

  }

  fclose(pRead);

  fclose(pWrite);

  memset(tStu,0×00,sizeof(tStu)); //清空数据

  //二进制文件打开文件 用于读取

  pRead=fopen("stu_scores_bin.txt","rb");

  if(NULL == pRead)

  {

  printf("open file stu_scores_bin.txt failed");

  return;

  }

  //下面有两种fread的读数据方式,将下面的1换成0,则使用第二种方式

  #if 1

  //一条条的读取

  ptStu = tStu;

  nCount = fread(ptStu,sizeof(struct student),1,pRead);

  while(nCount>0)

  {

  printf("%d %s %.1f %.1f %.1f\n",ptStu->nID,ptStu->chName,ptStu->fScores[0],ptStu->fScores[1],ptStu->fScores[2]);

  ptStu++;

  nCount = fread(ptStu,sizeof(struct student),1,pRead);

  }

  #else

  //因为事先知道有4条信息,因此可以直接读取四条信息

  fread(tStu,sizeof(struct student),4,pRead);

  for(nCount=0; nCount<4; nCount++)

  {

  printf("%d %s %.1f %.1f %.1f\n",tStu[nCount].nID,tStu[nCount].chName,tStu[nCount].fScores[0],tStu[nCount].fScores[1],tStu[nCount].fScores[2]);

  }

  #endif

  fclose(pRead);

  }

  上面用fread读取的时候,我们既可以一条条的读取,也可以一次读入多条,这就是为什么参数中有size和count的原因



查看完整回答
反对 回复 2019-03-26
  • 3 回答
  • 0 关注
  • 888 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信