我正在尝试制作一个程序来替换文件中的字符串。
我得到了下面的程序,它替换了文件中所有出现的一个字符串,但现在我需要扩展它,以便它将替换多个字符串。
简单的方法是多次运行程序,每次使用不同的字符串作为输入,但我正在寻找更有效的方法。
我的输入可以是:
- 要替换的字符串集(每个字符串出现一次)。
- 按出现顺序替换的字符串列表(字符串可以在列表中出现多次),但不知道它们的偏移量。
谢谢你的帮助。
#include <stdio.h>
#include <string.h>
#define LINE_LEN 128
int main(){
char fileOrig[32] = "orig.txt";
char fileRepl[32] = "new.txt";
char text2find[80];
char text2repl[80];
printf("enter text to replace in the file:");
scanf ("%s",text2find);
sprintf(text2repl,"%s%s%s","<b><font color="#FF0000">",text2find,"</font></b>");
char buffer[LINE_LEN+2];
char *buff_ptr, *find_ptr;
FILE *fp1, *fp2;
int buff_int;
size_t find_len = strlen(text2find);
fp1 = fopen(fileOrig,"r");
fp2 = fopen(fileRepl,"w");
buff_int=(int)buffer;
while(fgets(buffer,LINE_LEN+2,fp1)){
buff_ptr = buffer;
while ((find_ptr = strstr(buff_ptr,text2find))){
while(buff_ptr < find_ptr)
fputc((int)*buff_ptr++,fp2);
fputs(text2repl,fp2);
buff_ptr += find_len;
}
fputs(buff_ptr,fp2);
}
fclose(fp2);
fclose(fp1);
return 0;
}
有时候事情会变得复杂。假设你有字符串要替换为{ab,ba},它们将分别被替换为{xy,yx}。假设您有一个包含"aba"的输入文件。现在输出变成顺序相关的了。
如果替换一个字符串导致形成属于要替换字符串列表的另一个字符串,则会发生类似的混淆。
在我看来,你应该定义在这种情况下你想要做什么,然后使用类似于你已经做过的方法。
顺便说一句,您可以通过使用基于有限自动机的方法或使用一些现有的最先进的算法(如KMP或Boyer-Moore)来改进字符串匹配。这将允许您一次搜索多个字符串。
我不确定您想要的是否可能,但您可能希望查看字符串搜索算法,以使算法的搜索部分更加优化。根据维基百科,一个朴素的搜索算法的复杂度为Θ((n-m+1) m)
,其中n
是文本的长度,m
是搜索字符串的长度。看看这个链接,你可以做得更好。
一旦你有了要替换的字符串的所有偏移量,实际的替换似乎相当简单。
很抱歉我不能完全回答你的问题,但我认为这可能会给你一些优化的想法。
我想这会对你有帮助。请使用以下代码搜索& &;替换字符串
从顶层函数中调用这个函数,像这样:
replaceIPAddress("System.cfg"、"172.16.116.157","127.0.0.1");
void replaceIPAddress(char * confFileName, char *text_to_find, char *text_to_replace){
FILE *input = fopen(confFileName, "r");
FILE *output = fopen("temp.txt", "w");
char buffer[512];
while (fgets(buffer, sizeof(buffer), input) != NULL)
{
char *pos = strstr(buffer, text_to_find);
if (pos != NULL)
{
/* Allocate memory for temporary buffer */
char *temp = calloc(
strlen(buffer) - strlen(text_to_find) + strlen(text_to_replace) + 1, 1);
/* Copy the text before the text to replace */
memcpy(temp, buffer, pos - buffer);
/* Copy in the replacement text */
memcpy(temp + (pos - buffer), text_to_replace, strlen(text_to_replace));
/* Copy the remaining text from after the replace text */
memcpy(temp + (pos - buffer) + strlen(text_to_replace),
pos + strlen(text_to_find),
1 + strlen(buffer) - ((pos - buffer) + strlen(text_to_find)));
fputs(temp, output);
free(temp);
}
else
fputs(buffer, output);
}
fclose(output);
fclose(input);
/* Rename the temporary file to the original file */
rename("temp.txt", confFileName);
}
//
// Find and replace data in a file
//
// This is not as straightforward a problem as it initially appears,
// because if you have the text
//
// "Jack is a pirate"
//
// And you wish to replace "is" with "was", the string needs to be longer,
// or else you end up with the following:
//
// "Jack wasapirate"
//
// This becomes more of a problem for larger text. For example, if we wanted
// to replace "Jack" with "Rumpelstiltskin", we'd end up with:
//
// "Rumpelstiltskin"
//
// Which completely overwrites our original text!!!
//
// In order to do this correctly, we wither need to:
//
// 1. Read the entire file into a in-memory buffer
// 2. Write to a temporary file, then replace the original file
//
// Option #2 is easier to implement, and should work for your coursework.
//
#include <stdio.h>
int main(int argc, char** argv)
{
// We need a buffer to read in data
const int BufferSize = 0x1000;
char Buffer[BufferSize];
char *InputFileName = "input.txt";
char *TemporaryFileName = "temp.txt";
// Open the file for reading. 'rt' means that it must already exist, for reading.
FILE *Input = fopen(InputFileName, "rt");
// Our output file. 'w+' means to create the file if it doesnt exist, for writing.
FILE *Output = fopen(TemporaryFileName, "w+");
// Our find and replace arguments
char *Find = "is";
char *Replace = "was";
if(NULL == Input)
{
printf("Could not open file");
return 1;
}
printf("Find: %sn", Find);
printf("Replace: %sn", Replace);
// For each line...
while(NULL != fgets(Buffer, BufferSize, Input))
{
// For each incidence of "is"
char *Stop = NULL; // Where to stop copying (at 'is')
char *Start = Buffer; // Start at the beginning of the line, and after each match
printf("Line: %sn", Buffer);
while(1)
{
// Find next match
Stop = strstr(Start, Find);
if(NULL == Stop)
{
// Print the remaining text in the line
fwrite(Start, 1, strlen(Start), Output);
break;
}
// Write out everything between the end of the previous match, and the
// beginning of the current match.
//
// For example:
//
// "Jack is a pirate who is cool"
//
// Has two instances to replace. In order, we'd find them as such:
//
// "Jack is a pirate who is cool"
// ^
// ^
// What we want to do is write:
// - "Jack "
// - "was"
// - "a pirate who "
// - "was"
// - "cool"
printf("Match starts at: %sn", Stop);
// We have found a match! Copy everything from [Start, Stop)
fwrite(Start, 1, Stop - Start, Output);
// Write our replacement text
fwrite(Replace, 1, strlen(Replace), Output);
// Next time, we want to start searching after our 'match'
Start = Stop + strlen(Find);
printf("Search resumes at: %sn", Start);
};
}
// Close our files
fclose(Input);
fclose(Output);
// If desired, rename the Output file to the Input file
rename(TemporaryFileName, InputFileName);
return 0;
}