为什么ftell()在fread()之后显示错误的位置?

时间:2012-05-18 10:41:35

标签: c file fread

我尝试使用c fread()调用从简单的文本文件中读取时出现了一个非常奇怪的错误。
我做了一个非常简单的程序来显示错误:

int main(int argc ,char ** argv) {
  FILE* fh = fopen("adult.txt","r");
  if(fh==NULL){
    printf("error opening file\n");
    exit(0);
  }

  int s = 1000;
  printf("cur before=%d\n",ftell(fh));
  char* b = malloc (sizeof(char)*s);
  int k =fread(b,sizeof(char),s,fh);
  printf("cur after reading %d bytes =%d\n",k,ftell(fh));

  return EXIT_SUCCESS;
}

我得到的是输出:

cur before=0
cur after reading 1000 bytes =1007

这是正常的吗? fread返回数字' 1000'但是光标(用ftell())显示1007,任何帮助都将受到赞赏。

3 个答案:

答案 0 :(得分:10)

这是正常的。

'\n'可以用两个字符表示,因此存在偏差。

如果您不希望发生这种情况,请以二进制模式打开最后一个。

答案 1 :(得分:5)

来自ftell的文档:

  

或二进制流,返回的值对应于文件开头的字节数。 对于文本流,不保证该值是文件开头的确切字节数,但返回的值仍可用于使用fseek将位置指示器恢复到此位置。 < / p>

是的,这很正常。

答案 2 :(得分:1)

Let_Me_Be的回答是正确的。我在这里只是解释“行尾”(EOL)字符依赖于底层操作系统。例如,在Windows中,如果打开带有'r'(或非二进制)的文件,那么只要有'\ r \ n'序列,操作系统将只返回'\ n'。同样,当你在一个没有以二进制模式打开的文件中写入时,在Windows中,当你只是写'\ n'时它会写'\ r \ n'。对于Unix系统,操作系统没有这样的翻译。经典Mac会使用'\ r'作为End of Line字符,但我认为现在他们使用'\ n'表示EOL。我希望通过多个字符(\ r \ n)来清除'\ n'的流行语(可能)。