我需要替换某些文本中的字符串。我在 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 *
最佳答案
问题:
ret = malloc(i + count * (newlen - oldlen));
太小。需要+1。
考虑replace("", "", "")
会发生什么。如果您的 SO 引用号是 this ,也是错误的。混合有符号/无符号结果有问题。
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);
确保足够的空间。 @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/