需求
用户输入3个字符串,然后把在第一个字符串中出现的所有第 2 个字符串替换成第 3 个字符串,最后输出新的字符串。
比如:
第一个字符串:str: abcdefcdg ;第二个字符串:sub1: cd ;第三个字符串:sub2: 123
替换后的结果:ab123ef123g
思路
使用strstr逐个寻找子串,然后替换;替换的时候分为几步:
1. 将sub后面的内容向前或向前移动(因为replace可能大于sub也可能小于sub,所以可能向前复制或者向后复制),腾出空间
这里有个小技巧,假设子串开始的位置是p,那么被移动内存的起始位置是 p + subLen,移动到的位置是 p + replaceLen,长度是replaceLen;
2. 把replace拷贝到腾出的空间中。
3. 循环指针p移动到replace后的一个位置,再循环到前面用strstr查找下一个子串,再循环处理;如果strstr在后面找不到子串就直接退出了
注意:因为replace可能和sub长度不相等,所以需要不断更新长度,新长度为 len - sublen + replacesub;
代码实现
int strReplaceAll(char * str, char * sub, char * replace){
if(NULL == str || NULL == sub || NULL == replace){
printf("mystrcat param error\n");
return PARAM_ERR;
}
char * p = NULL;
char * t = NULL;
char * q = NULL;
char * dst = NULL;
char * src = NULL;
int len = strlen(str);
int len1 = strlen(sub);
int len2 = strlen(replace);
p = str;
while('\0' != *p){
t = str + len;
q = strstr(str, sub);
if(NULL == q) /*没有子串了,那么直接返回吧*/{
break;
}
src = q + len1; /*源头, 原有sub后的一个字符*/
dst = q + len2; /*目的,放完replace后的一个字符*/
memcpy(dst, src, t - src); /*原有字符串后移,放出空间*/
memcpy(q, replace, len2); /*将replace字符拷贝进来*/
len = len + len2 - len1;
p = q + len2; /* p 下一轮replace后的一个字符 */
}
str[len] = '\0'; /*通过'\0'表示结尾*/
}
void teststrReplaceAll(void){
char str[100] = "abcdefcdg";
char sub[100] = "cd";
char replace[100] = "123";
//char replace[100] = "2";
int num0 = 0, num1 = 0;
printf("\n************ teststrReplaceAll ************ \n");
strReplaceAll(str, sub, replace);
printf("After replace all, str is : %s\n", str);
return;
}
代码编译
gcc main.c str.c -g -o a.exe
调试输出
************ teststrReplaceAll ************
After replace all, str is : ab123ef123g