1

我有一个家庭作业,我们必须使用 .txt 文件。

这是我的文件示例:

1 约翰 1234 558
2 迈克 2222 9876
...

我想覆盖文件中的 558 号。给出了 ID (1,2...)。我一直在寻找, fopen() 函数只提供开始和追加的参数。

4

5 回答 5

5

您可以使用 fopen("filename", "r+b") 打开文件进行更新(以二进制模式)。然后,您可以使用 fseek 设置是否要写入下一个并使用 fwrite/fputs 或类似方法来更新数据。

例如,假设您从一个看起来像这样的文件test.text开始

0123456789abcde
0123456789abcde
0123456789abcde

您可以使用以下程序

#include <stdio.h>
int main(int argc, char **argv)
{
  FILE *f;
  if(!(f = fopen("./test.text", "r+b"))) //open the file for updating
    return -1;
  fseek(f, 16, SEEK_SET);//set the stream pointer 16 bytes from the start.
  const char message[] = "Hello, World!";
  fputs(message,f);
  return 0;
}

结果是

0123456789abcde
Hello, World!de
0123456789abcde

您仍然需要首先在文件中搜索要替换的 id,并且当您想用“12345”替换“558”时可能会遇到问题,除非行上有额外的空格来填充输出。因为您将从下一行开始覆盖数据。

于 2013-10-30T12:43:24.593 回答
2

fopen 打开文件,然后寻找正确的位,然后写入适当的位,小心不要覆盖文件中您不想覆盖的任何内容!

如果您需要插入比现有文本更多的数据,那么您必须从该点重新附加文件的其余内容。

于 2013-10-30T12:14:56.253 回答
1

有一些函数可以查找文件中的给定位置,但该位置是文件中的字节偏移量。您事先不知道偏移量,因此您需要逐行读取文件行,直到找到具有给定 ID 的行。然后你可以跳过名字,第一个数字,你在 558。现在的问题是你可以覆盖文件中的 558,但你不能写 12 并从 558 中删除 8。你也不能用 558 替换1234,因为您将用 123 覆盖 558,并且需要插入 4。

一个简单的解决方案是使用第二个文件。您可以每行读取文件 1 行并将每一行复制到文件 2。尽管具有给定 ID 的行。您将在将其写入文件 2 之前修改该行。

如果您知道如何操作,您也可以使用大缓冲区并在文件 1 中进行替换,而无需第二个文件。

如果允许您使用两个文件,则应该这样做。如果文件很短并且允许您将完整的文件读入内存,您可以读取文件,在内存中进行修改并写回文件。

于 2013-10-30T12:22:49.993 回答
1

重写整个文件通常更容易。您必须已经具有阅读和写作功能。所以你阅读,修改你的内存数据结构,然后你把所有的东西都写出来。

于 2013-10-30T12:26:49.907 回答
0

(假设您的 .txt 文件由上述 4 个字段组成)您可以拥有两个 FILE 指针,一个具有读取权限,另一个具有写入权限。假设您的文件名为 xyz.txt,让 fp_read 读取访问点,其中让 fp_write 指向新文件 xyz_bkp.txt。

变量
char *curr_line, *name;
int id,second_num,third_num;

这里的技巧是将文件 xyz.txt 逐行读取到一个字符串中(比如 curr_line),然后使用 sscanf 将行中的值读取到不同的变量中。例如- sscanf(curr_line, "%d %s %d %d", &id, name, &second_num, &third_num);

现在基于变量的值,要么无条件地将值写入 xyz_bkp.txt 文件,要么根据您的意愿更改它们。

注意:完成后,您需要删除原始 xyz.txt并将xyz_bkp.txt 重命名为 xyz.txt(足够简单)

于 2013-10-30T12:28:15.960 回答