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

请问,函数fread()和fwrite()的一些问题,具体看下面内容!

请问,函数fread()和fwrite()的一些问题,具体看下面内容!

慕仙森 2021-10-21 19:15:05
#include<stdio.h>struct cz{int month;float in;float out;}b[40]={0,0,0};int k=0; //将循环体中的限制条件k 设为全局变量。//k始终是你成功写入的次数。 void savedate(int k);void loaddate();void cheak();main(){ int input();int i;printf("如果你是第一次输入请留意是否有记录,如果有记录请先载入,再输入否则记录会被覆盖。\n\n\n");for(;;){ printf("1.输入收入或支出。\n2.查询某月记录。\n3.读取数据。\n4.离开\n");scanf("%d",&i);if(i==1){k=input(); //只写input()也可以。因为已经返回一个k值。k++; //保证k始终是你成功写入的次数。 }elseif(i==2)cheak();elseif(i==3)loaddate();elsebreak;}}int input(){ printf("请输入月份\n");scanf("%d",&b[k].month); //注意其中的k为全局变量。printf("请输入收入情况\n");scanf("%f",&b[k].in);printf("请输入支出情况\n");scanf("%f",&b[k].out);savedate(k+1); //将k加1传到函数savedate,因为savedate是void没有返回值,所以在input中k还是未加1前的值。return(k);} void cheak(){int i,n;float t=0;printf("请输入要查询的月份:\n");scanf("%d",&n);printf("您此次的记录是:\n");printf("月份\t收入\t支出\t总余额\n");for(i=0;i<k;i++){ if(b[i].month==n){printf("%3d\t%0.2f\t%0.2f\n",b[i].month,b[i].in,b[i].out);}}for(i=0;i<k;i++){if(b[i].month==n)t=t+b[i].in-b[i].out;}printf("\t\t\t%0.2f\n",t);}void savedate(int k){FILE *fp;int i;if((fp=fopen("count.txt","wb"))==NULL){printf("cannot open file\n");return;}fwrite(&k,sizeof(int),1,fp);//将你成功写入的次数k也写入文件。 这个语句的位置不能随便移动。为什么? 推测与读入顺序有关。 for(i=0;i<k;i++)  { if(fwrite(&b[i],sizeof(struct cz),1,fp)!=1) //先写入文件在判断是否为真. printf("file write error\n");}fclose(fp);}void loaddate(){FILE *fp;int i;if((fp=fopen("count.txt","rb"))==NULL){printf("cannot open file\n");return;}fread(&k,sizeof(int),1,fp); //读取之前成功写入的次数k。printf("月份\t收入\t支出\n"); for(i=0;i<k;i++){ fread(&b[i],sizeof(struct cz),1,fp);printf("%3d\t%0.2f\t%0.2f\n",b[i].month,b[i].in,b[i].out); //读取之前的数据,特别注意,打开文件不等于读取文件。打开之后不读,数据则不会还原。}fclose(fp);}问题主要是在void savedate(int k)函数中将 fwrite(&k,sizeof(int),1,fp);放到fclose(fp);前时程序会出错了。为什么。
查看完整描述

1 回答

?
白板的微信

TA贡献1883条经验 获得超3个赞

fwrite(&k,sizeof(int),1,fp)

k 是记录的个数,
本句是在文件中“第一个字”写入 一整形数标记了本文件中总的记录的个数
是在第一个字位置,当然不可以放到文件尾,在读如程序部分,首先读出该整形

在void loaddate() 中
fread(&k,sizeof(int),1,fp); //读取之前成功写入的次数k。

如果将 k write 到 文件尾 ,失去了意义,并且读出程序也需要修改
读出程序如果不能在开始判断出记录的个数,必须一次次检测直到读出遇到文件尾或是失败

不记录k 也可以家解决读取个数在读取前知道的问题

loaddate()中 使用

fseek(fp,0,SEEK_END);
long L=ftell(fp);
k=L/sizeof(cz);
fseek(fp,0,SEEK_SET);

查看完整回答
反对 回复 2021-10-24
  • 1 回答
  • 0 关注
  • 195 浏览

添加回答

举报

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