如何调整此算法以处理要修改的关键字的多次出现?

我想搜索所有出现的字符串(第一个参数),并在所有第一个字符串出现之前添加另一个字符串(第二个参数)。

理想情况下,我希望每一次出现的dime都用limedime代替。 然而,我设法做到了这一点,因为只有第一次出现这个词。 未检测到任何不匹配的匹配字符串,并且不执行任何操作。 此外,包含dime多行根据在前一行上进行的修改进行修改,这不是我想要的。

这是我得到的一些示例输出:

 something dime something dime something something 

会变成

 something limedime something dime something something 

如果我有这个

 dime notimportant! dime dime 

我会得到

 limedime notimportant! limelimedime limelimelimedime 

编辑:我已修改代码,以便您可以使用stdin轻松测试它,并且还包括replace_str()

 #include  #include  #include  char *replace_str(char *str, char *orig, char *rep) { static char buffer[4096]; char *p; if(!(p = strstr(str, orig))) return str; strncpy(buffer, str, p-str); buffer[p-str] = '\0'; sprintf(buffer+(p-str), "%s%s", rep, p+strlen(orig)); return buffer; } void replace(char* patternoo, char* replacearoo){ char buff[BUFSIZ]; // the input line char newbuff[BUFSIZ]; // the results of any editing char pattern[200]; strcpy(pattern, patternoo); char replace[200]; strcpy(replace, replacearoo); while ( fgets( buff, BUFSIZ, stdin ) != NULL ) { if ( strstr( buff, pattern ) != NULL ) { //THIS IS WHERE WE DO pattern replacing strcpy(newbuff, replace_str(buff, pattern, strcat(replace,pattern))); } else { strcpy( newbuff, buff ); } printf("%s", newbuff); } } int main(){ replace("dime", "lime"); } 

现在,我想也许这种方式不太好,因为我只是看着线条? 我不知道我能做什么,一个一个地阅读每一个角色? 对我来说似乎有点多,但我不太确定。 有没有快速而肮脏的方法来修复我当前的算法? 或者我是否必须重新开始并采取一种全新的方法?

假设你在每次出现dime之前插入lime ,你需要读一行,在输入缓冲区中找到每一个dime ,当找到时,将输入缓冲区的未处理部分复制到输出缓冲区,然后添加lime ,然后加dime ,然后在dime后继续搜索。

这意味着:

 #include  #include  #include  static void replace(char *pattern, char *replace) { char buff[BUFSIZ]; // the input line char newbuff[BUFSIZ]; // the results of any editing size_t replen = strlen(replace); size_t patlen = strlen(pattern); while (fgets(buff, BUFSIZ, stdin) != NULL) { newbuff[0] = '\0'; char *dst = newbuff; char *data = buff; char *patt; while ((patt = strstr(data, pattern)) != NULL) { memmove(dst, data, (patt - data)); dst += (patt - data); memmove(dst, replace, replen); dst += replen; memmove(dst, pattern, patlen); dst += patlen; data = patt + patlen; } *dst = '\0'; printf("%s%s", newbuff, data); } } int main(void) { replace("dime", "lime"); return 0; } 

代码轻率地忽略了输入行过长扩展的存在 – 你需要努力确保它不会溢出输出缓冲区。 由于每个dime (4个字符)插入4个字符( lime ),最坏的情况是输出中的空间需要两倍。 因此,更改newbuff[2 * BUFSIZ]的大小将处理那些溢出问题 – 对于您正在添加前缀的特定字符串。 超长输入线也可能导致未命中。 如果一个dime被分成两个缓冲区之间的边界,那么它就会被遗漏。

给定一个名为data的文件(根据您的问题编造):

 something dime something dime something something should become something limedime something limedime something something and if I have this dime not important! dime dime dime dime dime dime I will get limes and dimes galore: limedime not important! limedime limedime limedime limedime limedime limedime 

运行程序的输出( repstr ,我称之为)是:

 $ ./repstr < data something limedime something limedime something something should become something limelimedime something limelimedime something something and if I have this limedime not important! limedime limedime limedime limedime limedime limedime I will get limes and limedimes galore: limelimedime not important! limelimedime limelimedime limelimedime limelimedime limelimedime limelimedime $ 

一种方法可能是:

 Have a temp string that displays output. Until whole sentence read Read complete word of that sentence. if that word == dime append limedime to temp string else append the same word to temp string. 

DRYRUN:

 input: something dime somthing lime dime iteration1: something read compare it with lime, they arent equal so append somthing to temp string. temp: something iteration2: word read: dime temp: something limedime iteration3: word read: something temp: something limedime something and soo on. 

希望这种方法有帮助:)
多年没碰过C所以我忘了它的语法,所以无法帮助编码伪应该足够的。