c - 覆盖到c中的特定行

标签 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);

最佳答案

你几乎做不到这一点。

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

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

如果您小心地写入与行中已存在的字节数完全相同的字节数,您可能可以逃脱它 - 但在您的示例中,行的长度不同,因此这不是一个选项。

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

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

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

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

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

关于c - 覆盖到c中的特定行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11487869/

相关文章:

C malloc/free + fgets 性能

c - fseek(f,0,2);如果没有 SEEK_CUR/SEEK_SET 或 SEEK_END,这是如何工作的?

C,使用 printf 时的奇怪行为

c - 库中的链接器脚本变量阻止动态链接

c - 程序打印垃圾而不是函数调用的实际返回值

c++ - 写入文件mfc

node.js - 如何使用 Node js 更改文件中的特定行?

java - 在java中捕获系统默认编辑器关闭事件

Linux 操作系统类的内容

c - 如果以 "a+b"模式打开文件,fseek() 是否会将文件指针移动到文件开头?