恐惧的怪异行为

Weird behaviour with fread

我正在从文件中读取二进制 uint32_t 数据,指示下一个二进制块的大小,之后我读取了该块,但读取指针 "moving" 错误。

FILE* file = fopen("file.zip", "r");
long pointerA = ftell(file);
uint32_t streamSize = 0;
fread(reinterpret_cast<char*>(&streamSize), sizeof streamSize,1,file);
long pointerB = ftell(file);
char* zipData = new char[streamSize];
fread(zipData, sizeof(char),streamSize,file);

long pointerC = ftell(file);
fseek( file, pointerA + 4 + streamSize, SEEK_SET );
long pointerD = ftell(file);
qDebug()<<"streamSize"<<streamSize<<"Positions"<<pointerA<<pointerB<<pointerC<<pointerD;

PointerA是原始位置,PointerB是读完那个uint32_t后的位置,PointerC是读完那个二进制数据后的指针, PointerD 只是检查我认为应该是正确的行为。

现在让我们看看调试:

streamSize 2653 Positions 151 156 4627 2808

为什么流读取位置也移动了4627而不是2808?

提前感谢您的提示!

用户@alan-birtles 和@remy-lebeau 都是对的,我将其作为文本而不是二进制文件打开,这就是问题所在。

很遗憾,我无法将其标记为已解决。

PS。对于初学者,这意味着用 "rb" 而不是 "r" 打开文件。

您需要以二进制模式打开文件。当以文本模式打开文件时,某些字符会在您阅读时发生变化。例如在 Windows 上读取 '\n' 时返回“\r\n”。要以二进制模式打开,请将 'b' 添加到您的打开模式,例如:

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

请注意,您在编写二进制文件时需要执行相同的操作,否则会发生相同的转换。

std::fstream 也需要将 std::ios_base::binary 传递给 constructor/open 以避免同样的问题。