C-如果达到EOF,为什么fread()有两种可能的行为?
我不明白为什么函数fread()在这两个示例中的行为不同: 1)C-如果达到EOF,为什么fread()有两种可能的行为?,c,C,我不明白为什么函数fread()在这两个示例中的行为不同: 1) 我有一个包含一个short和一个char(大小为4字节,包括填充)的结构和一个由三个这样的结构组成的数组。如果我用fwrite()分别写入每个结构的short和char,然后用fread()将该文件读取到该结构类型的变量,我将一次读取4个字节(文件中有9个字节)所以你们可以看到,在第三次迭代中只剩下一个字节(每次迭代中都会丢失一个字节)。发生的情况是没有第三次读取,因为我只剩下一个字节,而fread必须读取4个字节 2) 一个
我有一个包含一个short和一个char(大小为4字节,包括填充)的结构和一个由三个这样的结构组成的数组。如果我用fwrite()分别写入每个结构的short和char,然后用fread()将该文件读取到该结构类型的变量,我将一次读取4个字节(文件中有9个字节)所以你们可以看到,在第三次迭代中只剩下一个字节(每次迭代中都会丢失一个字节)。发生的情况是没有第三次读取,因为我只剩下一个字节,而fread必须读取4个字节 2)
一个更简单的例子,如果我用fwrite()将一个1字节的字符写入一个文件,然后用fread()将该文件的内容放入一个4字节的int中,整数将获得该数据 为什么会发生这种情况?如果达到EOF,为什么在一种情况下读取数据,而在另一种情况下不读取数据 这是第一个例子:
int main()
{
struct X { short int s; char c; } y, x[]=
{{0x3132,'3'},{0x3435,'6'},{0x3738,'9'}};
FILE *fp=fopen("FILE.DAT","wb+");
if (fp)
{
for(int i=0;i<sizeof(x)/sizeof(x[i]);)
{
fwrite(&x[i].s,sizeof(x[i].s),1,fp);
fwrite(&x[i].c,sizeof(x[i].c),1,fp);
i++;
}
rewind(fp);
for(int i=0;fread(&y,sizeof(y),1,fp);)
printf("%d:%x %c\n",++i, y.s, y.c);
fclose(fp);
}
return 0;
}
。。。当达到EOF
时
EOF
未“达到”。许多
函数返回EOF
作为某个错误的信号,不给出该错误是什么。如果您想知道收到信号后出现了什么问题,请使用feof()
和/或ferror()
进行测试
如果达到EOF,为什么在一种情况下读取数据,而在另一种情况下不读取数据
“发生的事情是没有第三次读取,因为我只剩下一个字节,而fread必须读取4个字节。”这是一个可疑的前提
第一个代码读了3次。没有剩余的字节可读取
在这两个代码中,最后一次读取是部分读取,返回值为0。fread()
(第一个代码没有打印第三次读取的结果。)
对于fread()
,返回值为0并不意味着立即遇到“文件结束”-未读取任何内容。相反,0表示由于以下原因未发生完全读取:
*“文件结束”或部分读取。
*罕见的I/O错误
为什么会发生这种情况
在第二个代码中,结果可能因不确定行为而不同
fread()
。。。如果读取部分元素,其值为不确定C11dr§7.21.8.1 2
fread(&num,sizeof(num),1,fp)
一个信息量更大的例子
int main(void) {
FILE *fp = fopen("FILE.DAT", "wb+");
char c = 'a';
printf(" %8X\n", c);
fwrite(&c, sizeof(c), 1, fp);
rewind(fp);
unsigned num = rand();
printf(" %8X\n", num);
size_t len = fread(&num, sizeof(num), 1, fp);
printf("%zu %8X\n", len, num);
len = fread(&num, sizeof(num), 1, fp);
printf("%zu\n", len);
fclose(fp);
return 0;
}
输出
61 as expected
5851F42D as expected - some random value
0 5851F461 Indeterminate! (in this case, looks like the LSByte was replaced.)
0 as expected
故事的寓意:在依赖读入缓冲区的内容之前,先评估fread()
的返回值
1个不确定值
您是否可以编辑未指定的值或陷阱表示以提供一个?可运行代码比描述它的文本更具体。@Acorn没有文件,会编写一个新的文件(使用wb+,因为它既能写也能读)。您的两个示例中,哪一个是代码演示的示例?只是第一个,对吗?你对第一个例子有什么问题吗?或者问题是为什么第二个示例(我无法可视化,您没有显示代码)不同?您要求fread
读取一个大小为4的项目。大小为4的单个项目不存在(而且显然fread
不能返回0.5这样的值)。你希望发生什么fread
允许读取较少数量的项(如第二个示例所示),但读取部分项是不合理的。第二个示例不检查fread
的返回值,也不在调用int之前初始化int,然后检查int之后的值。您确定它读取的是一个整数的一部分吗?如果第一个程序中有第三次读取,那么为什么没有打印结果?@user3711671第三次读取返回0退出(int i=0;fread(&y,sizeof(y),1,fp);){}
循环-防止第三次调用printf()
。需要说明的是,数据是在第三个fread()
读取的,仅小于sizeof(y)
字节。
61 as expected
5851F42D as expected - some random value
0 5851F461 Indeterminate! (in this case, looks like the LSByte was replaced.)
0 as expected