C:循环中的字符串替换(c初学者)

标签 c string

我需要替换某些文本中的字符串。我在 stackoverflow 上找到了这个函数:

char *replace(const char *s, const char *old, const char *new)
{
    char *ret;
    int i, count = 0;
    size_t newlen = strlen(new);
    size_t oldlen = strlen(old);

    for (i = 0; s[i] != '\0'; i++) {
        if (strstr(&s[i], old) == &s[i]) {
        count++;
        i += oldlen - 1;
        }
    }

    ret = malloc(i + count * (newlen - oldlen));
    if (ret == NULL)
        exit(EXIT_FAILURE);

    i = 0;
    while (*s) {
        if (strstr(s, old) == s) {
            strcpy(&ret[i], new);
            i += newlen;
            s += oldlen;
        } else
            ret[i++] = *s++;
    }
    ret[i] = '\0';

    return ret;
}

这个功能对我来说非常适合单次替换。但我需要将整个数组“str2rep”替换为“替换”。所以我正在尝试做什么(我只是一个初学者)

****
    #define MAXTEXT 39016
    int l;
    int j;
    char *newsms = NULL;
    char text[MAXTEXT];
    char *str2rep[] = {":q:",":n:"};
    char *replacement[] = {"?","\n"};

    strcpy((char *)text,(char *)argv[5]);

    l = sizeof(str2rep) / sizeof(*str2rep);

    for(j = 0; j < l; j++)
    {
        newsms = replace(text,(char *)str2rep[j],(char *)replacement[j]);
        strcpy(text,newsms);
        free(newsms);       
    }

    textlen = strlen(text);

这段代码甚至可以在本地工作,如果我从单个文件构建它...但这是星号模块,所以当执行此代码时,星号会停止:

* 检测到 glibc */usr/sbin/asterisk:双重释放或损坏 (!prev):0x00007fa720006310 *

最佳答案

问题:

  1. ret = malloc(i + count * (newlen - oldlen));太小。需要+1。
    考虑 replace("", "", "") 会发生什么。如果您的 SO 引用号是 this ,也是错误的。

  2. 混合有符号/无符号结果有问题。 count已签署。 newlen, oldlen未签名。
    我认为原始代码工作正常,但我不喜欢使用无符号数学的环绕性质,当它可以避免时,这就是 newlen < oldlen 时发生的情况。 .

    // i + count * (newlen - oldlen)
    size_t newsize = i + 1;  // + 1 for above reason
    if (newlen > oldlen) newsize += count * (newlen - oldlen);
    if (newlen < oldlen) newsize -= count * (oldlen - newlen);
    ret = malloc(newsize);
    
  3. 确保足够的空间。 @hyde 这里提供各种方法。

    // strcpy(text, newsms);
    if (strlen(newsms) >= sizeof text) Handle_Error();
    strcpy(text, newsms);
    

轻微

  • 无需强制转换

    // newsms = replace(text, (char *) str2rep[j], (char *) replacement[j]);
    newsms = replace(text, str2rep[j], replacement[j]);
    
  • 更好地使用size_t对于 i 。迂腐的解决方案也会使用 size_t count .

    // int i;
    size_t i;
    
  • 关于C:循环中的字符串替换(c初学者),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25358392/

    相关文章:

    c - Malloc-动态内存分配

    C 中 int 转换为 char

    c++ - 在 Const char string[] 上使用字符串函数

    string - 防止格式字符串漏洞

    string - 通过指定子字符串的第一个和最后一个来提取字符串中的子字符串

    c - 如何确定音频设备上次播放文件的时间?

    c - 在 ncurses 中实现退格键工作的方法是什么

    c - 标记字符串后无法打印结果

    c++ - 在 visual studio 中调用 C/C++ 代码形成 fortran 程序? (如何在visual studio中编译混合的C和fortran代码)

    r - 确定字符向量中与匹配向量 [R] 中的最大匹配数相匹配的位置