0

我有一个程序,它接受用户提供的数据(整数、浮点数和字符串)并将其写入文本文件。现在我必须更新部分写入的数据。

例如:

在文件的第 4 行,我想更改前 2 个单词(有 anint和 a float)。我怎样才能做到这一点?

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

(解释代码将不胜感激,因为我是 C 语言的初学者)

4

3 回答 3

4

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

于 2013-03-26T18:20:17.503 回答
1

您确实需要阅读所有文件,并忽略不需要的内容。

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

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

在实践中,您可能特别想(或可能)使用行输入例程getlinefgets

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

如果您的文本文件具有非常规则的结构,您可能会fscanf在不关心行边界的情况下获取数据(忽略需要跳过的内容)。

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

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

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

顺便说一句,您可能对GDBM等索引文件感兴趣......甚至对SqlLiteMariaDbmongodb等数据库感兴趣......并且您可能对JSONYAML等标准文本序列化格式感兴趣(两者都有很多库,即使对于 C 来说,也要处理它们)。

于 2013-03-26T18:17:46.367 回答
0

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

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

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

于 2013-03-26T18:20:22.770 回答