同一文件流中的fread和fgetc不工作

fread and fgetc in the same file stream not working

本文关键字:fgetc 工作 fread 文件      更新时间:2023-10-16

我有一个二进制文件,其重复格式如下:6个浮点值+3个无符号字符(字节`,0到255之间的整数值)值。

我是这样分析的:

FILE *file = fopen("file.bin", "r");
bool valid = true;
while(!feof(file)) {
float vals[6];
valid = valid && (fread((void*)(&vals), sizeof(float), 6, file) == 6);
unsigned char a,b,c;
a = fgetc(file); b = fgetc(file); c = fgetc(file); 
(...)
}

这在前30次迭代中效果良好,但在那之后它就停止了解析(在文件结束之前)。

可能出了什么问题?

我还尝试使用解析unsigned char字节

fread((void*)&(a), sizeof(unsigned char), 1, file);

它只是简单地停止解析(在文件结束之前)。

您和C标准库在文件结尾的位置上存在意见分歧。ASCII字符EOF(对于DOS/Windows:十进制26,十六进制1A,又名Ctrl+Z,对于Unix/Linux:十进制4,十六进制04,又名Ctrl+D)是一个控制字符,意思是"文件结尾"。还有文件系统元数据存储的文件长度。

C stdio函数可以在几种模式下操作:文本、默认、二进制,这些模式控制几种行为:

  • 换行翻译(实现定义):在文本模式下启用,在二进制模式下禁用,默认值:
  • 文件结尾:实现定义,但通常是文本模式下的EOF字符,二进制模式下的文件系统文件长度,默认值:

由于您的文件包含二进制数据,您应该通过在模式字符串中使用"b"将二进制模式强制为fopen,例如

FILE* file = fopen("file.bin", "rb");

这样做时,值为26的字符将被视为其他任何字节,并失去其"EOF"的含义。