【问题标题】:behaviour of fseek and SEEK_ENDfseek 和 SEEK_END 的行为
【发布时间】:2014-12-18 15:11:21
【问题描述】:

如果我有一个包含以下内容的文本文件以二进制形式打开

1234567890

这样的调用:

fseek(fp, 5L, SEEK_SET);

当我调用 (char)fgetc(fp) 时给我 6,因为我从字节 0 偏移了 5 个字节(不是从 1 开始,而是从 2 开始)

但如果我这样做:

fseek(fp, -3L, SEEK_END);

当我打电话给 (char)fgetc(fp) 时,给我 8 而不是 7。

为什么?似乎与SEEK_END 一样,偏移量不是从最后一个字节之后的前一个字节开始的。

【问题讨论】:

  • 顺便说一句,您不必为SEEK_END 使用负值吗? (只是问,我不知道)
  • 哦,是的!我编辑了我的帖子。
  • ...我相应地编辑了我的答案。

标签: c fseek


【解决方案1】:

SEEK_END 从文件的最后一个字节开始搜索:

1234567890   <--- bytes from the file
0123456789A  <--- SEEK_SET-relative position
A9876543210  <--- SEEK_END-relative position (absolute value)
          ^
          This is the (0, SEEK_END) byte

考虑到这一点,文件的最后一个字节是在(-1, SEEK_END) 找到的那个,因此(-3, SEEK_END) 字节是8

请注意,这与 C 通常处理此类事情的方式是一致的。例如,指向内存块末尾的指针通常会指向该块的最后一个字节。

这还有一个不错的功能,您可以通过调用fseek(SEEK_END) 加上ftell() 来获取文件的大小。无需加减1

fseek() 的手册页对这个问题有点模棱两可,但与包含相同问题的 man lseek 相比:

如果whence是SEEK_END,则文件偏移量应设置为文件大小加上偏移量。

在您的示例中,文件大小为 10,偏移量为 -3,因此最终位置为 10-3 = 7。在偏移量 7 中有一个 8

【讨论】:

    【解决方案2】:

    fseek 允许将文本附加到当前文件。因此,文件指针设置在文件中的最后一个字符之后 (!),因为那是要添加新字符的地方。

    从头开始:

    01234         <---position
    ABCDEFGHIJK   <---file content
    

    从头到尾:

           43210  <---position
    ABCDEFGHIJK   <---file content
    

    因此,当您从头开始提取时,第 0 个字符是 A 第三个是D。

    但是当你从末尾获取时,第 0 个字符是 EndOfFile -3 是我。

    【讨论】:

      【解决方案3】:

      我认为是因为文件的最后一个字符是'\n''\0' 或类似的东西。

      【讨论】:

      • 在这个文件中没有'\n'。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-03
      • 2014-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-22
      相关资源
      最近更新 更多