【发布时间】:2018-05-24 04:51:08
【问题描述】:
以下代码获取一个原始 txt 文件,一个要在文件中搜索的字符串,以及一个替换原始字符串的新字符串。两个字符串的长度相同。此代码创建一个新文件(“new.txt”),将替换的文本写入那里,然后删除原始文件并将新文件重命名为原始文件。
问题是,我怎样才能使这段代码功能相同但不创建新文件?换句话说,我只想修改原始文件本身。我对原始文件(f)尝试了 fprintf,但它的输出很奇怪。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1024
int main(int argc, char *argv[])
{
FILE *f = fopen(argv[1], "r+");
FILE *f2 = fopen("new.txt", "a+");
if(strlen(argv[2])!=strlen(argv[3]))
printf("[%s] and [%s] have different lengths\n", argv[2], argv[3]);
char write[MAX];
int where;
char* string = NULL;
int len = strlen(argv[2]);
int i=0;
while(fgets(write, MAX, f)!=NULL)
{
if(NULL!=(string = strstr(write, argv[2])))
{
where = (int)(string - write);
strncpy(write+where, argv[3], len);
}
fprintf(f2, "%s", write);
}
remove(argv[1]);
rename("new.txt", argv[1]);
return 0;
}
【问题讨论】:
-
如果我想就地工作,我可能只需要
mmap文件。 -
使用 fputs 写入同一个文件。
-
检查
fseek -
fseek 到文件中第一次更改发生的位置,然后 fwrite 直到不需要进一步更改的位置。如果您要插入一行,那基本上意味着覆盖从该行到文件末尾的所有内容。但这实际上在文件系统上创建了一个新文件,它恰好具有相同的名称。与简单地写入新文件、删除原始文件并重命名新文件相比,数据的查找和写入将使文件锁定更长的时间。
-
在花时间打开文件之前检查字符串长度会更好——文件打开速度很慢,尤其是在创建文件时。当然,您最终只会使用一个文件。您需要跟踪每行的开始位置,以便您可以进行替换,寻找到您需要替换、写入和再次寻找的开始(从当前位置寻找零字节就足够了),然后再继续读。您必须在每个读取序列和下一次写入之间以及一系列写入(在本例中为一次)和下一次读取之间进行定位操作。