【问题标题】:Weird behaviour with freadfread 的奇怪行为
【发布时间】:2018-11-28 01:17:42
【问题描述】:

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

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?

提前感谢您的任何提示!

【问题讨论】:

  • 您是否以二进制模式打开文件?请发帖minimal reproducible example
  • 您是否偶然以文本模式而不是二进制模式打开文件?您对fread() 的第一次调用是将文件位置推进5 个字节而不是4 个字节。这可能在文本模式处理期间发生,特别是因为2653 包含字节0x0A,这很好地表明文本模式有效。你的问题被标记为 C++,那你为什么使用 C 风格的文件 I/O 而不是使用 C++ 文件流?
  • Remy 项目是用 c++ 制作的,但不幸的是使用这种方法是必需的(我没有选择它)

标签: c++ readfile fread seek


【解决方案1】:

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

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

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

【讨论】:

  • 请 Remy Lebeau 发表评论作为让每个人都开心的答案。
【解决方案2】:

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

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

请注意,您在编写二进制文件时也需要这样做,否则会发生相同的转换。

std::fstream 还需要将std::ios_base::binary 传递给构造函数/打开以避免同样的问题。

【讨论】:

    猜你喜欢
    • 2019-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 1970-01-01
    相关资源
    最近更新 更多