【问题标题】:Word replace in a string c字符串c中的单词替换
【发布时间】:2015-12-13 16:00:03
【问题描述】:

如何更改此代码以替换字符串中每个单词的出现,但不会替换所有子字符串。例如,如果单词是 ask,则不会替换 taskasking。因此,对于输入:“I'm ask a task ask my friend”和替换词:“for”输出应为:“I'm ask for a task for my friend”。

char *replace_word(char *string, char *word, char *new_word) {
    int len = strlen(string) + 1;
    char *temp = malloc(len * sizeof(char));
    int temp_len = 0;
    char *found;
    int len_w = strlen(word);
    while (found = strstr(string, word)) {
            if ((isalnum(*(found - 1))) || (isalnum(*(found + len_w)))) {
                    break;
            }
            else {

                    memcpy(temp + temp_len, string, found - string);

                    temp_len = temp_len + found - string;

                    string = found + strlen(word);

                    len = len - strlen(word) + strlen(new_word);
                    temp = realloc(temp, len * sizeof(char));

                    memcpy(temp + temp_len, new_word, strlen(new_word));

                    temp_len = temp_len + strlen(new_word);
            }
   }

    strcpy(temp + temp_len, string);

return temp;
  }

在这个阶段,如果输入是:“它问我这个任务?”就可以了。输出是:“这个任务是给我的?”但是如果输入是这样的:“我问这个问朋友”,输出将与输入相同,因此代码不会进行更改。需要帮忙!

【问题讨论】:

    标签: c string function malloc


    【解决方案1】:

    好的,所以发生的情况是,在它发现子字符串中出现单词后,while循环中断;

    if ((isalnum(*(found - 1))) || (isalnum(*(found + len_w)))) {
                    break;
            }
    

    相反,它应该复制单词和它之前的所有内容,以便 while 不会进入无限循环,因为它会一遍又一遍地找到相同的事件。 此更改应使其生效:

    char *replace_word(char *string, char *word, char *new_word) {
        int len = strlen(string) + 1;
        char *temp = malloc(len * sizeof(char));
        int temp_len = 0;
        char *found;
        int len_w = strlen(word);
        while (found = strstr(string, word)) {
                if ((isalnum(*(found - 1))) || (isalnum(*(found + len_w)))) {
              memcpy(temp + temp_len, string, found - string + strlen(word));
    
              temp_len = temp_len + found - string + strlen(word);
    
              string = found + strlen(word);
    
                }
                else {
    
                        memcpy(temp + temp_len, string, found - string);
    
                        temp_len = temp_len + found - string;
    
                        string = found + strlen(word);
    
                        len = len - strlen(word) + strlen(new_word);
                        temp = realloc(temp, len * sizeof(char));
    
                        memcpy(temp + temp_len, new_word, strlen(new_word));
    
                        temp_len = temp_len + strlen(new_word);
                }
       }
    
        strcpy(temp + temp_len, string);
    
    return temp;
      }
    

    【讨论】:

    • 不客气,还有一件事我忘了提是:使用 while ((found = strstr(string, word))) 避免任何编译器警告,不带括号编写它检查赋值返回值根据 C99,第 6.5.16 节是赋值后左操作数的值,因此对于 C99 或更新的编译器来说是完全相同的
    【解决方案2】:

    您在代码中还有一些其他问题,但是:

           if ((isalnum(*(found - 1))) || (isalnum(*(found + len_w)))) {
                    break;
            }
    

    这是核心问题——一旦你确定这个词被一个字母数字字符包围,你想跳到下一个出现的地方,但你在这里做的就是完全打破循环。

    你想做的是:

            if ((isalnum(*(found - 1))) || (isalnum(*(found + len_w)))) {
                    continue;
            }
    

    'break' 中断循环。

    'continue'继续到下一次迭代。

    确保在找到每个匹配项后更新字符串,否则您将陷入无限循环,一遍又一遍地从 strstr() 函数获取相同的指针。

    【讨论】:

    • 我意识到 break 结束了我的循环,但我不知道该怎么做。因此,当找到一个由字母数字包围的单词时,似乎我错过了“更新”。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2015-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-01
    相关资源
    最近更新 更多