我已经获得了一些在服务器上运行的代码,直到它被移动到另一个系统。问题似乎在这里:
给出了我在其他地方定义的结构:
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()?它是否因文件类型而异?
答案 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)。