覆盖到c中的特定行

时间:2012-07-14 22:31:10

标签: c file fseek fputs ftell

我有一个大约2000行文本的文件,我在我的程序中生成,每行都有一个员工的信息,它就像这样输出了

  

1 1 Isaac Fonseca 58 c 1600 1310.40 6 1 0.22 2164.80 1
  2 1 Manuel Gutierrez 22 d 1700 1523.37 4 1 0.13 897.26 1
  3 1 Daniel Bernal 34 c 1600 1195.84 2 1 0.26 836.16 1
  4 1 Miguel Gonzalez 43 e 1800 1195.84 0 1 0.15 0.00 1

但是,每当我编辑员工信息时,我必须更新文件,我正在做的是我搜索该行并尝试重写它

我见过有关同一问题的人的以下问题,但当我尝试写入文件时,它总是写到文件末尾

overwriting a specific line on a text file?

这是我的代码:

datos = fopen(archivo,"a+");
for(i=0;i<num;i++){
    // buscar la linea
    fgets(lineaA,100,datos);
    // sobreescribir
    if(i == (num-1))
        cursor = ftell(datos);                      
}

cursor -= strlen(lineaA) - 1;
fseek(datos,cursor,SEEK_CUR);

fputs(linea2,datos);            
fclose(datos);

3 个答案:

答案 0 :(得分:3)

你几乎不能这样做。

您可以使用fseek转到文件中的特定位置,然后您可以将数据写入该位置(您可能希望使用"r+"模式)。

但是文件通常存储为一系列字节(或字符),而不是一系列行。

如果你要小心写出行中已经存在的完全相同的字节数,你可以放弃它 - 但在你的例子中,这些行的长度各不相同,所以这不是一个选项。

例如,您可以使用空白填充每一行,因此它们的长度都相同,但如果您使用普通文本编辑器修改文件,则很容易破坏布局。

对于文本文件,通常的方法是将文件读入内存,修改内存中的表示,然后重新创建整个文件。您可能希望将内容写入新的临时文件,然后在确认没有写入错误后将其重命名。

这就是文本编辑通常所做的事情。

(不要过分担心效率; 2000行不是那么大,你也不会注意写它们所需的时间。)

还有其他选择。您可以使用固定长度记录定义二进制格式,也可以使用数据库。或者您可以在文件中添加新行,并将重复项视为它们已被删除(但如果您进行大量更新,这会导致文件变得非常大)。

答案 1 :(得分:1)

除非像家庭作业那样需要自己滚动所有代码,否则切换到数据库可能最容易。鉴于你有其余的代码工作,SQLite可能是最明显的选择。

如果你真的想坚持(至少类似于)你当前的格式和代码,我可能会写入数据,每行填充到64或128字节(如果你有一些记录去更长时间,隔离它们,例如将它们全部移动到文件末尾,或将它们放在单独的文件中)。这种方式(大多数?)编辑可以在不影响其他行的情况下完成。如果你有一个雇员的行索引,你也可以直接寻找那一行,而不是阅读它的所有前辈来找到它。

答案 2 :(得分:0)

您正在使用选项“a +”打开文件,该选项仅允许您附加到文件,而不是覆盖。你想使用“r +”

datos = fopen(archivo,"r+);