在C中查找并替换所有出现的子字符串

时间:2016-09-08 22:23:51

标签: c string replace

我正在尝试查找并替换C中字符串数组中所有出现的子字符串。我认为我的大部分逻辑已经失效,但是我不知道我在哪里搞乱剩下的部分。

以下是相关代码 - 我要替换的字符串位于searchStr,我正在尝试将其替换为replaceStr。字符串数组称为buff。我不需要将修改后的字符串保存回数组后,我只需要将修改后的字符串打印到控制台。

for (size_t i = 0; i < numLines; i++) {
        char *tmp = buff[i];
        char finalStr[MAX_STR_LEN * 2];
        char temporaryString[MAX_STR_LEN];
        int match = 0;
        while ((tmp = strstr(tmp, searchStr))) {
            match = 1;
            char temporaryString[MAX_STR_LEN];
            char tmp2[MAX_STR_LEN];
            printf("Buff[i]: %s", buff[i]);

            sprintf(temporaryString, "%s", strstr(tmp, searchStr) + strlen(searchStr)); // Grab everything after the match
            printf("Behind: %s", temporaryString);

            strncpy(tmp2, buff[i], tmp - buff[i]); // Grab everything before the match
            strcat(finalStr, tmp2);
            printf("In Front: %s\n", finalStr);

            strcat(finalStr, replaceStr); // Concat everything before with the replacing string

            tmp = tmp + strlen(searchStr);
            buff[i] = tmp; // Move buff pointer up so that it looks for another match in the remaining part of the string
        }
        if (match) {
            strcat(finalStr, temporaryString); // Add on any remaining bytes
            printf("Final: %s\n", finalStr); 
        }
    }

如果有很多printf那么我就可以看到调试的所有内容。

示例案例:

如果我使用what4is4thissearchStr = 4对着字符串replaceStr = !!!运行它,这就是控制台中的输出...我也在使用//添加注释

Buff[i]: what4is4this           // Just printing out the current string before we attempt to replace anything
Behind: is4this                 // Looking good here
In Front: hat                   // Why is it cutting off the 'w'? 
Buff[i]: is4this                // Good - this is the remaining string we need to look through
Behind: this                    // Again, looking good
In Front: hat!!!isat            // It should be 'is'
Final: hat!!!isat!!!isat        // final should be 'what!!!is!!!this'

任何想法的家伙?我试图解决这个问题而撕裂我的头发

谢谢!

1 个答案:

答案 0 :(得分:0)

这是指针杂耍和未定义行为的不健康组合,但评论者已经告诉过你。如果你简化了一点并且使用指针做得很好而节俭,你可以做类似的事情:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// ALL CHECKS OMMITTED!

#define MAX_STR_LEN 1024

int main(int argc, char **argv)
{
  char *buff, *cpbuff;
  char *searchStr;
  char *replaceStr;

  // pointers too the two parts with the search string in between
  char *tmp, *after;
  // the final output (a fixed length is not good, 
  // should be dynamically allocated)
  char finalStr[MAX_STR_LEN * 2] = { '\0' };

  if (argc < 4) {
    fprintf(stderr, "Usage: %s string searchstr replacestr\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  buff = malloc(strlen(argv[1]) + 1);
  strcpy(buff, argv[1]);
  searchStr = malloc(strlen(argv[2]) + 1);
  strcpy(searchStr, argv[2]);
  replaceStr = malloc(strlen(argv[3]) + 1);
  strcpy(replaceStr, argv[3]);

  // Keep a finger on the start of buff
  cpbuff = buff;
  while (1) {
    printf("Buff: %s\n", buff);
    // Grab everything after the match
    after = strstr(buff, searchStr);
    // No further matches? Than we're done
    if (after == NULL) {
      strcat(finalStr, buff);
      break;
    }
    // assuming strlen(searchStr) >= 1
    tmp = buff;
    // mark the end of the first part
    tmp[after - buff] = '\0';
    // set the after pointer to the start of the second part
    after = after + strlen(searchStr);
    printf("Behind: %s\n", after);
    printf("Before: %s\n\n", tmp);
    // Put the first part to it's final place
    strcat(finalStr, tmp);
    // concat the replacement string
    strcat(finalStr, replaceStr);
    // Set buff to the start of the second part
    buff = after + strlen(searchStr) - 1;
  }
  printf("Final: %s\n", finalStr);
  // set the buff pointer back to it's start
  buff = cpbuff;

  free(buff);
  free(searchStr);
  free(replaceStr);

  exit(EXIT_SUCCESS);
}

可以称为滥用指针算术的单点是标记第一部分结束的行。可以通过测量和使用所涉及的字符串的长度来避免它并与它们进行算术运算。考虑到它的速度较慢,因此取决于您的个人用例。

它比我喜欢它还要复杂,但它是一个开始。

我希望你现在可以将它扩展到几行输入。