2

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

1 1 ISAAC FONECA 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

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

我已经看到有同样问题的人的以下问题,但是当我尝试写入文件时,它总是写入文件末尾

覆盖文本文件上的特定行?

这是我的代码:

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);
4

3 回答 3

3

你几乎不能这样做。

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

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

如果您小心地写入与行中已经存在的字节数完全相同的字节,您可能会侥幸成功——但在您的示例中,行的长度不同,因此这不是一个选项。

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

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

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

(不要太担心效率;2000 行并不是那么大,而且你不会注意到编写它们所花费的时间。)

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

于 2012-07-14T22:45:56.880 回答
1

除非这类似于家庭作业,您需要自己滚动所有代码,否则切换到数据库可能是最简单的。鉴于您的其余代码都在工作,SQLite可能是最明显的选择。

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

于 2012-07-14T22:50:11.983 回答
0

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

datos = fopen(archivo,"r+);
于 2012-07-14T22:44:15.380 回答