2013-03-26 126 views
0

我有一个程序,它接受用户给出的数据(int,浮点数和字符串)并将其写入文本文件中。现在,我必须更新该写入数据的一部分。文本文件编辑C

例如:

在文件中的行4我想改变前2个字(有一个intfloat)。我怎样才能做到这一点?

有了我发现的信息,fseek()fputs()可以使用,但我不知道如何到达特定线路。

+0

你能改变那个数据文件的格式吗?你认为是JSON还是YAML?在C中有几个JSON解析器,例如jansson – 2013-03-26 18:45:38

回答

1

你真的需要阅读所有的文件,而忽略不需要什么

(因为我是一个起动机用C代码的解释可以理解的)。

fseek并不真正有用:它将文件定位在某个字节偏移处(相对于文件的开始或结尾)并且不知道行边界。

实际上,文件中的行是一个不明确的概念。通常一行是由换行符('\n')结尾的字节序列(不同于换行符)。某些操作系统(Windows,MacOSX)以特殊的方式读取文本文件(例如,实际文件包含\r\n以结束每一行,但C库让您错过了您已阅读\n)。

实际上,您可能想要使用line input routines,特别是getline(或者可能是fgets)。

如果您使用getline您应该关心free -ing行缓冲区。

如果您的文本文件具有非常规则的结构,那么您可能需要fscanf数据(忽略您需要跳过的内容)而不关心行边界。

如果您想绝对使用fseek(这是一个错误),您将不得不读取文件两次:第一次记住每行开始(或结束)的位置,第二次到fseek到行开始。但是,这对更新不起作用,因为您不能在文件中插入字节。

实际上,最昂贵的操作是实际读取磁盘。缓冲(部分由内核和<stdio.h>函数完成,部分由你在处理行时完成)可以忽略不计。

当然,你不能在文件中改变一些行。如果您需要这样做,请处理文件以进行输入,生成一些输出文件(包含修改的输入)并在完成时重命名。

顺便说一句,你或许会对感兴趣的索引文件,如GDBM等等......甚至像SqlLiteMariaDbmongodb等....,你可能会感兴趣的标准文本的序列化格式像JSONYAML数据库(他们都有很多库,即使是C,也要处理它们)。

4

您不能在文件中“插入”字符。您将不得不创建程序,它将读取整个文件,然后复制部分,然后插入到新文件,版本和文件的其余部分。

0

fseek()用于随机访问文件,其中每个数据记录具有相同的大小。通常数据是二进制的,而不是文本。

要解决您的特定问题,您需要一次读取一行以找到您想要更改的行。进行更改的简单方法是将这些行写入临时文件,将更改写入相同的临时文件,然后从原始文件中跳过要更改的部分,并将重置复制到临时文件。最后,关闭原始文件,将临时文件复制到它,然后删除临时文件。

这样说的话,我建议你多了解随机存取文件。这些在存储所有相同大小的记录时非常有用。如果您可以控制创建原始文件,这些可能会更适合您当前的目的。

+0

我不完全相信随机访问二进制文件总是一个很好的答案。它们当然会带来自己的负担:数据的不可移植性(除非您关心一些与架构无关的序列化格式),人类几乎无法察觉,脆弱等等。 – 2013-03-26 19:21:27