覆盖到c中的特定行
我有一个大约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
但我每当我编辑员工信息时我都要更新文件,我正在做的是我搜索该行并尝试重写它
我已经看到了有同样问题的人的以下问题,但是当我尝试写入文件时,它总是写入文件的末尾
覆盖文本文件中的特定行?
这是我的代码:
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行并不是那么大,你不会注意写它们所花费的时间。)
还有其他选择。 您可以使用固定长度记录定义二进制格式,也可以使用数据库。 或者,您可以在文件中添加新行,并将重复项视为已删除(但如果您进行大量更新,这会导致文件变得非常大)。
除非像家庭作业那样需要自己滚动所有代码,否则切换到数据库可能最容易。 鉴于你有其余的代码工作, SQLite可能是最明显的选择。
如果你真的想坚持(至少类似于你当前的格式和代码),我可能会写入数据,每行填充到64或128字节(如果你有一些记录更长,隔离它们,例如将它们全部移动到文件的末尾,或者将它们放在单独的文件中)。 这种方式(大多数?)编辑可以在不影响其他行的情况下完成。 如果您拥有员工的行索引,您还可以直接查找该行,而不是阅读其所有前任以找到它。
您正在使用选项“a +”打开文件,该选项仅允许您附加到文件,而不是覆盖。 你想用“r +”
datos = fopen(archivo,"r+);