覆盖到c中的特定行

覆盖到c中的特定行,c,file,fseek,fputs,ftell,C,File,Fseek,Fputs,Ftell,我有一个大约2000行文本的文件,我在我的程序中生成,每行都有一个员工的信息,输出如下 1艾萨克·丰塞卡58 c 1600 1310.40 6 1 0.22 2164.80 1 2曼努埃尔·古铁雷斯22 d 1700 1523.37 4 1 0.13 897.26 1 3 1丹尼尔·伯纳尔34 c 1600 1195.84 2 1 0.26 836.16 1 4 1米格尔·冈萨雷斯43 e 1800 1195.84 0 1 0.15 0.00 1 但我每次编辑员工信息时都要更新文件,我要做的是搜

我有一个大约2000行文本的文件,我在我的程序中生成,每行都有一个员工的信息,输出如下

1艾萨克·丰塞卡58 c 1600 1310.40 6 1 0.22 2164.80 1
2曼努埃尔·古铁雷斯22 d 1700 1523.37 4 1 0.13 897.26 1
3 1丹尼尔·伯纳尔34 c 1600 1195.84 2 1 0.26 836.16 1
4 1米格尔·冈萨雷斯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);
datos=fopen(archivo,“a+”);

对于(i=0;i您正在使用选项“a+”打开文件,该选项仅允许您附加到文件,而不允许覆盖。是否要使用“r+”


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


你几乎不能这么做

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

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

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

例如,您可以在每一行中填充空格,使其长度相同,但如果您使用(比如)普通文本编辑器修改文件,则很容易损坏布局

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

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

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


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

您几乎无法做到这一点

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

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

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

例如,您可以在每一行中填充空格,使其长度相同,但如果您使用(比如)普通文本编辑器修改文件,则很容易损坏布局

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

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

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


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

除非这像是家庭作业,你需要自己滚动所有的代码,否则切换到数据库可能是最容易的。考虑到剩下的代码都在工作,这可能是最明显的选择


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

除非这类似于家庭作业,您需要自己滚动所有代码,否则切换到数据库可能是最容易的。Gi即使剩下的代码都能正常工作,也可能是最明显的选择


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

这很棘手--
a+
打开进行追加,这不是您想要的。可能
r+
,或者您必须使用不同的open命令。但我从未尝试过这样做。(请注意,您需要使用与原始行完全相同的字节数进行覆盖。)@HotLicks将其更改为
r+
,并将其附加到代码中的特定行,现在我只需要重新设置
datos = fopen(archivo,"r+);