我有字符串“{”1“:”[4,11,14,19,20,18,27]“}”。我想改成它 “{\”。1 \ “:\” 4,11,14,19,20,18,27 \ “}”
以下是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *replace (char *this, char *withthat, char *inthis) {
char *where = inthis;
while ((where = strstr(where, this))) {
memcpy(where, withthat, strlen(withthat));
memmove(where+strlen(withthat),where+strlen(this), strlen(where+strlen(this))+1);
}
return inthis;
}
int main(void) {
char string[] = "{"1":"[4,11,14,19,20,18,27]"}";
printf("%s\n", replace(""", "\\\"", string));
printf("%s\n", replace("\"[" , "\"", string));
printf("%s\n", replace("]\\" , "\\", string));
printf("%s\n", replace("{" , "\"{", string));
printf("%s\n", replace("}" , "}\"", string));
return 0;
}
我收到最后两个替换呼叫的错误。我的o / p是{\“1 \”:\“[4,11,14,19,20,18,27] \”} {\ “1 \”:\ “4,11,14,19,20,18,27] \”} {\ “1 \”:\ “4,11,14,19,20,18,27 \”} 分段错误
我尝试过做gdb,但无法找到错误的根本原因。它在某种程度上与memcopy有关,但无法理解。如果有人能帮助我,那就太好了。提前谢谢。
答案 0 :(得分:1)
您的替换字符串比输入长,但是当您分配string
时,它只有输入大小和NUL终结符的空间。当你尝试扩展它时,你会超出缓冲区,系统会关闭你(虽然它可能会让你有一个小的超限,例如将分配四舍五入到下一个4或8的倍数。
要解决此问题,您(可能)想要计算字符串增长的最大数量,分配大量的字符串,并将其用于结果。
修改:例如,考虑您的上次替换,将}
更改为}"
。这会使您找到的子串的长度加倍。作为一个非常简单的最坏情况估计,我们假设整个输入完全由}
组成。在这种情况下,结果将是输入的两倍,因此我们需要为结果分配strlen(input)*2+1
个字节。
在您的情况下,最后四个替换(至少)是互斥的(例如,输入可以是{
和}
以及[
和一个]
同时加倍长度一次足以覆盖所有长度。
答案 1 :(得分:1)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *replace (char *old, char *new, char *buff) {
char *ptr;
size_t oldlen = strlen(old);
size_t newlen = strlen(new);
for(ptr=buff; ptr = strstr(ptr, old); ptr += newlen) {
memmove(ptr+newlen, ptr+oldlen, strlen(ptr+oldlen)+1);
memcpy(ptr, new, newlen);
}
return buff;
}
int main(void) {
char string[1234] = "{"1":"[4,11,14,19,20,18,27]"}";
printf("%s\n", replace(""", "\\\"", string));
printf("%s\n", replace("\"[" , "\"", string));
printf("%s\n", replace("]\\" , "\\", string));
printf("%s\n", replace("{" , "\"{", string));
printf("%s\n", replace("}" , "}\"", string));
return 0;
}
最后两个替换“{}”包含自己。这会导致原始字符串在同一位置重新扫描,重新匹配+重新置位。无限。 ptr + = newlen避免了这种情况。
答案 2 :(得分:0)
您的replace
假设缓冲区足够大以容纳结果。您需要将缓冲区分配得如此之大,以至于它可以保存扩展结果。
答案 3 :(得分:0)
您的操作顺序错误。您应该首先为替换字符串添加位置,而比插入替换字符串。 (给予足够的空间)。此外,您可以提前计算strlen()s,因为它们不会更改。 (除非他们只使用一次)
答案 4 :(得分:0)
如果长于此值,那么你的memcpy会覆盖替换后的字符串的一部分。在这种情况下,你必须在memcpy之前做memmove。