C语言中fread的一些疑问

void read(struct student s[],int *pn)
{
FILE *fp;
int count;
//int n=2;
if((fp=fopen("2009.dat","rb"))==NULL)
{
printf("cannot open the file\n");
exit(0);
}
count=0;
while (!feof(fp))
{

if(fread(&s[count],sizeof(struct student),1,fp)!=0)
count++;
}
fclose(fp);
*pn=count;

}

我看书上fread的格式是fread(buffer,size,count,fp);
然后例子是fread(fa,4,5,fp);
可是我上面的代码里buffer位置直接输入s为什么读取的时候会变成乱码?而必须用&s[count]?

L_o_o_n_i_e 回答得不怎么准确!

我帮你解释下:

首先介绍fread函数

功 能: 从一个流中读数据
函数原型: int fread(void *ptr, int size, int nitems, FILE *stream); 参 数:用于接收数据的地址(指针)(ptr)
单个元素的大小(size) :单位是字节而不是位,例如读取一个整数值就是4 元素个数(nitems)
提供数据的文件指针(stream)
返回值:成功读取的元素个数

由上面介绍知道fread函数的第一个参数是个指针变量,可以指向任意类型实参!

严归正传,对于你这里的问题, 你代码中的s是个结构体数组变量,跟普通数组变量一样,数组名本身就是个指针常量,所以在buffer位置写成s是没有问题的。
那么为什么你这里读会变乱码呢?
虽然你帖的代码并没有全,但从你说的读取是乱码, 我大概猜到在你用fwrite函数把数据写进文件的时候是以每次一个结构体大小(也就是仅仅是数组s的一个元素而已,也就对应一个下标而已)和一个数据块的方式写进文件里的。 所以当你用fread函数读取的时候,假设你在buffer位置写成s,本身语法是没有问题的,但是就相当于你把数组s的仅一个元素的数据大小当成所有s的数据存到s中,也就是没有对应起来,所以显示会是乱码。

所以你可以有两种方式实现:

方式一:
在写的时候按一次以s的一个元素的数据大小作为一个数据块依次写进文件,然后读取时候也以同样方式读出来。
代码可以这么写:
假设s的大小为:SIZE_S
for(count = 0; count < SIZE_S; count++)
fwrite(&s[count], sizeof(struct student), 1, fp);
然后读取时:
for(count = 0; count < SIZE_S; count++)
fread(&s[count], sizeof(struct student), 1, fp);

方式二:
以整个数组s的数据大小作为一个数据块一次写进文件,然后读取时也同样全部读出来,最后可以以循环的方式打印出来。
代码实现如下:
假设s的大小为:SIZE_S
fwrite(s, SIZE_S * sizeof(struct student), 1, fp);
然后读取时:
fread(s, SIZE_S * sizeof(struct student), 1, fp);
最后打印:
for(count = 0; count < SIZE_S; count++)
fread(&s[count], sizeof(struct student), 1, fp);

明白了记得给哥哥顶下~~~ ^_^
温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-06-29
因为s 来自 参数 struct student s[],结构数组
fread 函数原型,参数1 是 指针。所以实参 要填 地址 &s[0] 或 &s[几]
相似回答