首页技术fread返回值为0,fread返回值是什么

fread返回值为0,fread返回值是什么

编程之家2026-07-031182次浏览

大家好,今天给各位分享fread返回值为0的一些知识,其中也会对fread返回值是什么进行解释,文章篇幅可能偏长,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在就马上开始吧!

fread返回值为0,fread返回值是什么

C语言中fread的一些疑问

L_o_o_n_i_e回答得不怎么准确!

我帮你解释下:

首先介绍fread函数

功能:从一个流中读数据

函数原型: int fread(void*ptr, int size, int nitems, FILE*stream);参数:用于接收数据的地址(指针)(ptr)

单个元素的大小(size):单位是字节而不是位,例如读取一个整数值就是4元素个数(nitems)

fread返回值为0,fread返回值是什么

提供数据的文件指针(stream)

返回值:成功读取的元素个数

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

严归正传,对于你这里的问题,你代码中的s是个结构体数组变量,跟普通数组变量一样,数组名本身就是个指针常量,所以在buffer位置写成s是没有问题的。

那么为什么你这里读会变乱码呢?

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

fread返回值为0,fread返回值是什么

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

方式一:

在写的时候按一次以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);

明白了记得给哥哥顶下~~~ ^_^

C语言fread函数问题

fer, size_t Size, size_t Count, FILE* Stream);

Size:每个要读取的元素的大小,单位字节----第二个参数

Count:要读取的元素个数------------------第三个参数

函数的返回值是实际读出元素的个数。

fwrite的第二和第三个参数及返回值的含义同上。

用fread(temp,1024,1,fp)也能读出,意思是一个元素的大小是1024个字节,每次读取一个,这在读取前面内容时没问题,当读到最后,加入只剩下100个字节的数据,不足1024字节时,程序返回0,你无法知道程序最后一次读出了多少数据。如果用fread(temp,1,1024,fp),则程序每次返回读出数据的字节数,即使读最后100个字节时,也返回100,这样你可以利用返回值知道程序读出了多少数据。

你程序中用'\0'判断读出数据的结束标志,也是有问题的。mp3文件中本身就有很多NULL字符,用strchr(temp,'\0');返回的指针未必指向读出数据的结束标志,可能指向读出数据中的某位。我实际试验了一下,用这种方法,4M多的1.mp3,最终只能得到800多k的2.mp3。正确的做法是利用fread的返回值作为fwrite的输入。

最终程序修改如下,去除了打印代码:

#include<stdio.h>

#include<string.h>

void main()

{

FILE*fp;

FILE*fpw;

char temp[1024];

int bsize;

fp=fopen("c:/book/1.mp3","rb");

fpw=fopen("c:/book/2.mp3","wb");

if(fp==NULL)

{

printf("can not open file\n");

}

temp[1023]='\0';

while(!feof(fp))

{

bsize= fread(temp,1,sizeof(temp)-1,fp);

fwrite(temp,1,bsize,fpw);

}

fclose(fp);

fclose(fpw);

}

fread大概只能读10k

错误原因:

你用文本方式打开了二进制文件

文本方式读取二进制数据,可能在文件结束之前将某段数据判定为文件末尾EOF,所以结束读取(举个例子,比如遇到 0x00 0x00 0xff 0xff,则文本方式方式的文件流,认为已经到文件末尾,不能读取)

你这个38016的文件,大概在10k左右有段数据和文件结束标志格式相同,文本方式读取到10k左右就认为文件结束了(真正的文本文件,结束标志可能在磁盘簇的剩余空间中)

所以第一种方式:

固定读取38016次,每次往新文件中写一个字节;前10k次能读取到内容, fread返回值是1,这样写过去的一字节就是读取的字节;后28k因为读取失败, fread返回值为0,这样temp的内容就不会被改写,仍然是最后一次成功读取的值,但因为是写次数固定,所以后28k就重复写过去;

后一种方式:

根据fread的返回值来判定文件结束,这是正确的方法;所以读取到10k后,返回值为0,表示无效,文件结束,所以只复制了10k内容

CFile只支持二进读写,所以你的结果是正确的( CFile用CFile::typeText格式会报错; CStdioFile才能文本读写)

用fopen返回的FILE,如果读取的时候没有加b(比如"r"),则默认的是文本格式;所以请用"rb"来读取二进制文件,用"wb"写二进制文件;当然如果只是复制文件的话,纯二进制读写没有问题

下面是楼主要的效果,是一个字节读写的

#include<stdio.h>

int main()

{

FILE*pFileS= fopen("s.rar","rb");

if(! pFileS)

return 1;

FILE*pFileD= fopen("d.rar","wb+");

unsigned char bTemp;

while( fread(&bTemp, sizeof(unsigned char), 1, pFileS))

fwrite(&bTemp, sizeof(unsigned char), 1, pFileD);

fclose( pFileS), fclose( pFileD);

return 0;

}

其实一个字节读写的话,用fgetc和fputc就可以了,当然还是得以二进制方式打开

另外单字节读写速度太慢;系统中复制文件都是整块读写的,设置缓冲大小

比如

#include<stdio.h>

int main()

{

FILE*pFileS= fopen("s.rar","rb");

if(! pFileS)

return 1;

FILE*pFileD= fopen("d.rar","wb");

unsigned char buffer[ 4* 1024 ];

int nRead;

while( nRead= fread( buffer, sizeof(unsigned char), sizeof(buffer), pFileS))

fwrite( buffer, sizeof(unsigned char), nRead, pFileD);

fclose( pFileS), fclose( pFileD);

return 0;

}

另外, fread单次读取的总字节数有限制,也就是说缓冲有上限;只能通过提高次数来读取大文件;在这方面,用API如ReadFile或者调用了这些API的封装类就好得多;当然,次数多对电脑来说不是问题呵呵

附:

至于文本方式不能完全读取,而二进制方式能的原因-

文本方式读取文件,最主要的用处是一次读取一整句(以换行符'\n',即二进制的换行标志"\r\n"结束),方便用于特殊用处ReadString、fscanf(...,"%s",...)之类,每次读取的内容长度是不定的;而二进制读取方式Read、fread等,都是读取固定长度

所以文本方式读取对EOF的判定,是一个文件尾结束标志,如果是文本文件,则这个文件尾肯定不会出现在文件内容中(因为是不可打印字符构成的结束标志,人可读的文本文件不会包括它),这样以结束标志为文件尾则是可以的;二进制文件内容可以是任意字节,如果把它当文本文件来读,以文件尾为结束,当然可能出现把文件内容判定为文件尾的情况;

二进制读取方式由于每次读取固定字节,所以只需要用总文件长度(这个数值是系统管理的数值,不是计算得出来的)减去每次读取的长度(或根据Seek的位置计算长度),就可以知道是否到文件尾,不需要定义结束标志;所以用二进制方式打开任何文件都是合理的

END,本文到此结束,如果可以帮助到大家,还望关注本站哦!

div+css布局(使用div加css页面布局的介绍)html元素,html指什么