替换字符串中的单词

时间:2013-08-19 13:06:13

标签: c string strcmp strstr

这是我想做的一个例子 我有以下列表

[token]
[token1]
[token22]
[token99]
[8token]
[3token3]

我要删除“[”和“]”然后用我自己的单词替换单词标记。所以我有以下代码:

char *getToken(char *repl, char *mysrc)
{
    const char *p1 = strstr(mysrc,"[")+1;
    const char *p2 = strstr(p1,"]");
    size_t len = p2-p1;
    char *src = (char*)malloc(sizeof(char)*(len+1));
    strncpy(src,p1,len);
    src[len] = '\0';

    char *find = "token";
    char *found;
    if(strcmp(src,find) == 0)
        return src;
    char *res = malloc(strlen(src) + strlen(repl) + 1);
    if (res == NULL)
        return src;
    found = strstr(src, find);
    /* Search string not found, return the whole of the source */
    if (found == NULL){
        strcpy(res, src);
        return res;
    }
    /* Paste the replacement string in */
    strncpy(res, src, (size_t)(found - src));
    strcat(res, repl);
    strcat(res, found + strlen(find));
    free(src);
    return res;
}

工作正常,但在某些情况下,我在结果前面得到一个X或H.像这样:Xtest22而不是test22

我是否对strlen做错了什么?我似乎无法找出我做错的地方。

1 个答案:

答案 0 :(得分:4)

"token"字符串在删除方括号后在字符串的开头结束时,可能会发生这种情况:在这种情况下,(size_t)(found - src)的计算结果为零,因此调用

strncpy(res, src, (size_t)(found - src));

根本不会更改res字符串,留下任何垃圾,以便在追加之前跳过以下strcat调用。幸运的是,res中的垃圾恰好是一个以空字符结尾的短字符串,例如"X""H"。否则,您可以获得更长的任意字符串。

除了修复上述未定义的行为之外,还应该修改一些内容:

  • 您的代码不会检查第一个malloc
  • 的返回值
  • 您的代码错误地计算了结果的长度:您应该减去单词"token"的长度,因为您将其替换为repl的内容,即它应该是malloc(strlen(src) + strlen(repl) - strlen(find) + 1) < / LI>
  • 您无需在C
  • 中转换malloc的返回值
  • 您不需要将长度乘以sizeof(char)(只有两个malloc中的一个会这样做)
  • 你的第二次早期回归会泄漏记忆。