在二进制附加中获取ftell()的问题

时间:2016-04-27 16:58:30

标签: c++ c

我已经获得了一些在服务器上运行的代码,直到它被移动到另一个系统。问题似乎在这里:

给出了我在其他地方定义的结构:

user1_type user1;              /* structure containing user data */
user1_type *user1_ptr=&user1;

此例程将记录追加到文件末尾

if ((dfile=fopen(filename,"ab+"))==NULL)  
  error_message("Unable to open file for append.",filename,1);
 else { /* append data */
 user1.recid=ftell(dfile);               /* update file position */

 fwrite(user1_ptr,sizeof(user1),1,dfile);
 fflush(dfile);
 fclose(dfile);

我可以确认数据是否附加在文件中,但是user1.recid的值总是返回0 - 任何想法为什么?

更新:看起来问题并非所有实现都需要在fopen()之后使用fseek()。我显然需要一个fseek(dfile,0,SEEK_END);在我附加ftell()之前。但是,如果我想从文本或二进制文件的开头读取,是否习惯于在fopen之后放置一个fseek()?它是否因文件类型而异?

3 个答案:

答案 0 :(得分:3)

来自MSDN的ftell

文档
  

ftell()返回的位置表示为偏移相对值   到流的开头

     

如果在打开要追加的文件上尚未发生I / O操作,   文件位置是文件的开头。

这使您相对于开头的偏移量为0。

因此,当您调用user1.recid=ftell(dfile);时,流上没有发生I / O操作,因此ftell()返回0表示文件指针位置在开头。

答案 1 :(得分:3)

此处ftell(dfile)的此行为将是实现定义的。从C11 7.21.3(以前的C标准中的类似措辞):

  

如果文件可以支持定位请求(例如磁盘文件,则为   与终端相对),然后是与之关联的文件位置指示符   流位于开头(字符编号为零)的位置   文件,,除非文件是以附加模式打开的,在这种情况下是   实现定义文件位置指示符是否为   最初位于文件的开头或结尾。

答案 2 :(得分:2)

...所以(除了bkVnet的回答)你必须使用fseek(dfile,0,SEEK_END)寻找结尾,问ftell这个位置并将其除以sizeof(user1_type)获取记录ID(即文件中已有的记录数,因此新记录加1)。