即使文件位置指针位于正确的位置,fwrite也会附加

时间:2017-01-16 02:00:25

标签: c

我想覆盖二进制文件中的结构。这是我的代码 :

struct my_st {
  char value[10];
};

void replace(char value[10]){
FILE *fpointer;
fpointer = fopen("data.dat", "rb+");
struct my_st x;
struct my_st new;
new.value="test";
while(1) {
 fread(&x,sizeof(x),1,fpointer);
 if(strcmp(x.value,value)==0)
   break;
}
  fwrite(&new,sizeof(x),1,fpointer);
}

我甚至通过在fwrite之前打印它的值来检查文件位置指针的位置并且它是正确的但它只是在文件末尾添加新数据而不替换。

有什么建议吗?

1 个答案:

答案 0 :(得分:4)

如果您打开文件进行更新(+),并且执行了一项或多项读取操作,则必须先执行定位操作(例如fseek()),然后再进行任何写入操作。如果执行一个或多个写入操作,则必须在执行任何读取之前执行定位操作(例如rewind())。例如,请参阅POSIX的fopen()规范。

  

当使用更新模式('+'作为mode参数中的第二个或第三个字符)打开文件时,可以在关联的流上执行输入和输出。但是,应用程序应确保输出不会直接跟随输入,而无需调用fflush()或文件定位功能(fseek()fsetpos()rewind())除非输入操作遇到文件结束,否则输入不会直接跟随输出而没有对文件定位功能的干预调用。

您在读取和写入之间没有进行任何定位操作。这本身就会导致不确定的行为。

假设您的实施展示了未定义的行为'在你的最后一个fread()之后,你不会忘记行为不端,你会写下一个条目 - 或者如果最后一个条目是在文件的末尾,则附加一个新条目。

  • 确定您希望写入数据的位置。
  • 寻找正确的位置(如果您不想移动读/写指针,请使用fseek(fp, 0L, SEEK_CUR)。)
  • 写入。
  • 如果你接下来要读书,那就做另一次寻求 - 如果需要,可以另外做一次。