使用 fseek 时出现意外输出

5
假设我们有一个名为hi.txt的文本文件,其中包含以下字符串:

AbCdE12345

假设我们运行以下代码:
int main() {
  FILE *fp;
  fp = fopen("hi.txt","r");
  if(NULL == fp) { return 1; }
  fseek(fp,-1, SEEK_END);
  while (ftell(fp) > 0) {
     printf("%c",fgetc(fp));
     fseek(fp,-4, SEEK_CUR);
  }
  fclose(fp);
  return 0;
}

当我运行这段代码时,它打印出了:3EbCd 当我试图猜测它会打印出什么时,我认为应该是52d。有人能解释一下发生了什么吗?
2个回答

15
看起来你的文件末尾有一个不可打印的换行符。它会被首先打印出来。然后位置依次移动到3、E和b。此时,通过-3重新定位失败,因为位置将变为-2。文件光标停留在原地,即在C处,接下来打印出C。下一次重新定位也失败了,所以d被打印出来。下一次重新定位成功,循环结束。
要检测fseek被忽略的情况,请检查其返回值,像这样:
while (ftell(fp) > 0) {
    printf("%c",fgetc(fp));
    // Successful calls of fseek return zero
    if (fseek(fp,-4, SEEK_CUR)) {
        // Exit the loop if you can't jump back by 4 positions
        break;
    }
}

4

对于以文本模式打开的文件,传递给fseek的偏移量仅对ftell返回的值有意义。因此,偏移量可能不一定以字节为单位。尝试以二进制模式打开文件:

fp = fopen("hi.txt", "rb");

并查看结果是否不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接