关于fwrite和fread函数的使用。望指点,谢谢!

koo8 2009-01-13 04:40:58
最近在温习c时,写了个小程序要实现的功能:输入三条记录写入文件stu1中,
然后读取显示,在wintc中,调试通过,显示结果总读不对。
程序如下:
/* NONAME.C -- file write and read */

#include "stdio.h"
#include "conio.h"
#include "malloc.h"

struct stu
{
char sno[2];
char sname[3];
int age;
};


main()
{

int i;
struct stu *s=(struct stu*)malloc(sizeof(struct stu));
FILE *fpw,*fpr;

printf("\n\n======write======\n");

fpw=fopen("stu1","ab");
if(fpw)
{
for(i=0;i<3;i++)
{
printf("sno:");
scanf("%s\n",&s->sno);

printf("sname:");
scanf("%s\n",&s->sname);

printf("age:");
scanf("%d\n",&s->age);
/*
printf("sno,sname,age:\n");
scanf("%s,%s,%d\n",&s->sno,&s->sname,&s->age);
s->sno[2]='\0';
s->sname[3]='\0';
*/
fwrite(s,sizeof(struct stu),1,fpw);
}
}
else
{
printf("open failed!");
exit(0);
}
/**/
printf("\n\n======read======\n\n\n");

fpr=fopen("stu1","rb");
if(fpr)
{
i=0;
while(!feof(fpr))
{
fseek(fpr,i*sizeof(struct stu),0);
fread(s,sizeof(struct stu),1,fpr);
printf("sno:%s\n",s->sno);
printf("sname:%s\n",s->sname);
printf("age:%d\n",s->age);

i++;
}
}
else
{
printf("open failed!");
exit(0);
}
printf("\n==over==\n");
free(s);

getch();
}
...全文
277 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
koo8 2009-01-15
  • 打赏
  • 举报
回复
谢谢各位,基本上明白了,结贴!
wyswyg63 2009-01-14
  • 打赏
  • 举报
回复


#include "stdio.h"
#include "conio.h"
#include "malloc.h"
#include <stdlib.h>

struct stu
{
char sno[4]; //这里是字符串,最后一位需要\0, 为了字节对齐,最好创建4字节,但是你输入时最多输入3个字符
// int sno; 你可以考虑改为整型
char sname[4]; //同上
int age;
};


void main()
{

int i;
struct stu *s=(struct stu*)malloc((sizeof(struct stu)));
FILE *fpw,*fpr;

printf("\n\n======write======\n");

fpw=fopen("stu1","wb");
if(fpw)
{
for(i=0;i <3;i++)
{
printf("sno:");
//scanf("%s",&s->sno);
scanf("%s",s->sno); //s-sno已经是地址了

printf("sname:");
scanf("%s",s->sname); //同上

printf("age:");
scanf("%d",&s->age);
/*
printf("sno,sname,age:\n");
scanf("%s,%s,%d\n",&s->sno,&s->sname,&s->age);
s->sno[2]='\0';
s->sname[3]='\0';
*/
fwrite(s,sizeof(struct stu),1,fpw);
}
}
else
{
printf("open failed!");
}
fclose(fpw);
/**/
printf("\n\n======read======\n\n\n");

fpr=fopen("stu1","rb");
if(fpr)
{
i=0;
while(fread(s,sizeof(struct stu),1,fpr))
{
/*fseek(fpr,i*sizeof(struct stu),0);*/

printf("sno:%s\n",s->sno);
printf("sname:%s\n",s->sname);
printf("age:%d\n",s->age);
/* i++;*/
}
}
else
{
printf("open failed!");
exit(0);
}
printf("\n==over==\n");
fclose(fpr);
free(s);
getch();
}


如输入:
sno:01
sname:aaa
sno:02
sname:bbb
age:21
sno:01
sname:ccc
age:22

结果:
sno:01aaa
sname:aaa
age:20
sno:02bbb
sname:bbb
age:21
sno:01ccc
sname:ccc
age:22

分析:
sno:01 //你先输入2个字符,你创建的char sno[2] 只有2字节,scanf输入时字符串结束符\0加在后面,越界了,
\\也就是sname[0]这个字符是\0.
sname:aaa //char sname[3],这里你再用scanf,上面sname[0]的\0字符被覆盖,你输入三个字符,字符串又越界了,
\\scanf函数在sname[3]后面一个字节空间中加\0;
然后看你的结构体,紧接是一个int类型,为了保证字节对齐,所以编译器会在sname[3]后面补3字节空间,所以后面再输入age的时候,\0不会被覆盖。
结构体相当于
struct stu
{
char sno[2];
char sname[3];
char reserve[3]; //字节对齐,编译器自动会空3个空间出来,
int age;
};

当你打印的时候,用的是%s, %s是遇到\0才结束。 在你结构体中,只有reserve[0]这个字节是\0,所以出现上面情况
代码小鼠 2009-01-14
  • 打赏
  • 举报
回复
scanf("%s",&s->sno);
应该写成
scanf("%s",s->sno);

不应该加地址符了,因为s->sno已经是数组的首地址了!!
neeestth 2009-01-14
  • 打赏
  • 举报
回复
顶 楼上强人。
  • 打赏
  • 举报
回复
mark,帮顶
neeestth 2009-01-13
  • 打赏
  • 举报
回复
不好意思,结果不对。在学习学习。
neeestth 2009-01-13
  • 打赏
  • 举报
回复

#include "stdio.h"
#include "conio.h"
#include "malloc.h"
#include <stdlib.h>

struct stu
{
char sno[2];
char sname[3];
int age;
};


void main()
{

int i;
struct stu *s=(struct stu*)malloc((sizeof(struct stu)));
FILE *fpw,*fpr;

printf("\n\n======write======\n");

fpw=fopen("stu1","wb");
if(fpw)
{
for(i=0;i <3;i++)
{
printf("sno:");
scanf("%s",&s->sno);

printf("sname:");
scanf("%s",&s->sname);

printf("age:");
scanf("%d",&s->age);
/*
printf("sno,sname,age:\n");
scanf("%s,%s,%d\n",&s->sno,&s->sname,&s->age);
s->sno[2]='\0';
s->sname[3]='\0';
*/
fwrite(s,sizeof(struct stu),1,fpw);
}
}
else
{
printf("open failed!");
}
fclose(fpw);
/**/
printf("\n\n======read======\n\n\n");

fpr=fopen("stu1","rb");
if(fpr)
{
i=0;
while(fread(s,sizeof(struct stu),1,fpr))
{
/*fseek(fpr,i*sizeof(struct stu),0);*/

printf("sno:%s\n",s->sno);
printf("sname:%s\n",s->sname);
printf("age:%d\n",s->age);
/* i++;*/
}
}
else
{
printf("open failed!");
exit(0);
}
printf("\n==over==\n");
fclose(fpr);
free(s);
getch();
}

结果多了吧。
koo8 2009-01-13
  • 打赏
  • 举报
回复
谢谢各位关注!我疏忽了文件关闭这块儿。

回1楼:
你说的是: scanf("%s",&s->sno); /*你的scanf有问题*/
是不是应该改成:scanf("%s",&s->sno);

回2楼:
fseek(fpr,i*sizeof(struct stu),0); //这句不需要吧,每次fread后文件读写指针都会自动移动
fread(s,sizeof(struct stu),1,fpr); //这里最好判断读出的字节是不是sizeof(struct stu)
是的,fseek可以不要,
fread应该验证一下取得的字节大小。

回3楼:
请问,我写了 struct stu *s=(struct stu*)malloc(sizeof(struct stu));分配空间 memset(s, 0, sizeof(struct stu));//这句是必须要的吗?
可是在wintc中找不到头文件:#include "memory.h"


在各位的指教下,有点头绪了
我验证一下结果还是不正确,写入和读取的结果不一样。
如输入:
sno:01
sname:aaa
age:20
sno:02
sname:bbb
age:21
sno:01
sname:ccc
age:22

结果:
sno:01aaa
sname:aaa
age:20
sno:02bbb
sname:bbb
age:21
sno:01ccc
sname:ccc
age:22

我想应该是输出的问题,估计没有字符串结束表识,在输出sno时直接把sname也一块儿输出了。
方法一:在写入文件之前要加入字符结束符
方法二:根据实际读取出来的数据,控制字符大小来输出
大家有没有好的意见?谢谢!

weidong0210 2009-01-13
  • 打赏
  • 举报
回复
学习
xiaoyisnail 2009-01-13
  • 打赏
  • 举报
回复

#include "stdio.h"
#include "conio.h"
#include "malloc.h"
#include "memory.h"

struct stu
{
char sno[2];
char sname[3];
int age;
};


int main()
{
int i;
struct stu *s=(struct stu*)malloc(sizeof(struct stu));
memset(s, 0, sizeof(struct stu));
FILE *fpw,*fpr;

printf("\n\n======write======\n");

fpw=fopen("stu1","ab");
if(fpw)
{
for(i=0;i <3;i++)
{
printf("sno:");
scanf("%s",s->sno);

printf("sname:");
scanf("%s",s->sname);

printf("age:");
scanf("%d",&s->age);

fwrite(s,sizeof(struct stu),1,fpw);
}
}
else
{
printf("open failed!");
exit(0);
}

printf("\n\n======read======\n\n\n");

fclose(fpw);//记得关闭

fpr=fopen("stu1","rb");
if(fpr)
{
while(fread(s,sizeof(struct stu),1,fpr))//这样写就可以了
{
printf("sno:%s\n",s->sno);
printf("sname:%s\n",s->sname);
printf("age:%d\n",s->age);
}
}
else
{
printf("open failed!");
exit(0);
}
printf("\n==over==\n");
free(s);

fclose(fpr);
getch()

return 0;
}
wyswyg63 2009-01-13
  • 打赏
  • 举报
回复
while(!feof(fpr))
{
fseek(fpr,i*sizeof(struct stu),0); //这句不需要吧,每次fread后文件读写指针都会自动移动
fread(s,sizeof(struct stu),1,fpr); //这里最好判断读出的字节是不是sizeof(struct stu)
printf("sno:%s\n",s->sno);
printf("sname:%s\n",s->sname);
printf("age:%d\n",s->age);

i++;
}
}
lbh2001 2009-01-13
  • 打赏
  • 举报
回复

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

struct stu
{
char sno[2];
char sname[3];
int age;
};

int main(void)
{
int i;
struct stu *s=(struct stu*)malloc(sizeof(struct stu));
FILE *fpw,*fpr;

printf("\n\n======write======\n");

fpw=fopen("stu1","ab");
if(fpw)
{
for(i=0;i <3;i++)
{
printf("sno:");
scanf("%s",&s->sno); /*你的scanf有问题*/

printf("sname:");
scanf("%s",&s->sname);

printf("age:");
scanf("%d",&s->age);
/*
printf("sno,sname,age:\n");
scanf("%s,%s,%d\n",&s->sno,&s->sname,&s->age);
s->sno[2]='\0';
s->sname[3]='\0';
*/
fwrite(s,sizeof(struct stu),1,fpw);
}
}
else
{
printf("open failed!");
exit(0);
}
/**/
printf("\n\n======read======\n\n\n");
fclose(fpw);
fpr=fopen("stu1","rb");
if(fpr)
{
i=0;
while(fread(s,sizeof(struct stu),1,fpr))
{
//fseek(fpr,i*sizeof(struct stu),0);
//fread(s,sizeof(struct stu),1,fpr);
printf("sno:%s\n",s->sno);
printf("sname:%s\n",s->sname);
printf("age:%d\n",s->age);

i++;
}
}
else
{
printf("open failed!");
exit(0);
}
printf("\n==over==\n");
free(s);
fclose(fpr);
getch();
}

70,020

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧