目录

方案1

方案2

方案三

第四种方案

思考


方案1

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>/*
有字符串有以下特征(“abcd11111abcd2222abcdqqqqq”),求写一个函数接口,
输出以下结果。
把字符串替换成(dcba11111dcba2222dcbaqqqqq),并把结果传出。
要求:
1. 正确实现接口和功能
2. 编写测试用例
/*
src:                原字符串
dst:                ⽣成的或需要填充的字符串
sub:                需要查找的⼦字符串
new_sub:提换的新⼦字符串
return  :   0   成功
-1  失败
*/int   replaceSubstr(/*    in  */char  *src,   /*  out */char**    dst,/*  in  */char  *sub,       /*  in  */char  *new_sub)
{char *out = NULL;char *p = NULL;char *q = NULL;int sub_len = 0;int new_sub_len = 0;if (src == NULL || dst == NULL || sub == NULL || new_sub == NULL) {fprintf(stderr, "(src == NULL || dst == NULL || sub == NULL || new_sub == NULL)\n");return -1;}out = (char*)malloc(sizeof(char) * 4096);if (out == NULL) {fprintf(stderr, "malloc out error\n");return -1;}memset(out, 0, 4096);p = src;q = p;sub_len = strlen(sub);new_sub_len = strlen(new_sub);while ((p = strstr(p, sub)) != NULL) {//找到了子串strncat(out, q, p - q);strncat(out, new_sub, new_sub_len);p += sub_len;q = p;if (*p == '\0') {break;}}if (*q != '\0') {strncat(out, q, (src + strlen(src) - q));}*dst = out;return 0;
}int main(void)
{char *str = "abcd213213abcddjisoabcd2131abcd";char *dst = NULL;replaceSubstr(str, &dst, "abcd", "X");printf("dst: %s\n", dst);replaceSubstr(str, &dst, "abcd", "dcba");printf("dst: %s\n", dst);return 0;
}

方案2

#include <stdio.h>
#include <string.h>
#include <stdlib.h>//函数: str_replace
//功能: 将字符串s中所有f的内容替换成r的内容
//返回: 新字符串的地址(使用free释放), 失败返回0。
char * str_replace(const char * s, const char * f, const char * r)
{int inum = 1;int if_len, ir_len;char * ps;char * pt;char * pn;char * pp;if (s == 0 || f == 0 || r == 0) return 0;if (s[0] == 0 || f[0] == 0) return 0;if_len = strlen(f);ir_len = strlen(r);for (ps = (char *)s;;){pt = strstr(ps, f);if (pt == 0){inum += strlen(ps);break;}inum += (pt - ps) + ir_len;ps = pt + if_len;}pn = pp = (char*)malloc(inum);if (pn == 0) return 0;pn[inum - 1] = 0;for (ps = (char *)s;;){pt = strstr(ps, f);if (pt == 0){memcpy(pp, ps, strlen(ps));break;}memcpy(pp, ps, pt - ps);pp += pt - ps;memcpy(pp, r, ir_len);pp += ir_len;ps = pt + if_len;}return pn;
}int main(void)
{char * cstr;char * cnew;cstr = "Good morning.";cnew = str_replace(cstr, "morning", "evening");if (cnew != 0){puts(cnew);free(cnew);}cstr = "aa..bb..cc..dd..!";cnew = str_replace(cstr, "..", "");if (cnew != 0){puts(cnew);free(cnew);}return 0;
}

方案三

#include <iostream>#include<stdio.h>#include<string.h>
char *replace(char* source, char *sub, char *rep)
{char *result;///*pc1  是复制到结果result的扫描指针*////*pc2  是扫描 source 的辅助指针*///   /*pc3  寻找子串时,为检查变化中的source是否与子串相等,是指向sub的扫描指针 */// /*找到匹配后,为了复制到结果串,是指向rep的扫描指针*/char *pc1, *pc2, *pc3;int isource, isub, irep;isub = strlen(sub);/*对比字符串的长度*/irep = strlen(rep); /*替换字符串的长度*/isource = strlen(source);/*源字符串的长度*/if (NULL == *sub) return _strdup(source);/*申请结果串需要的空间*/result = (char *)malloc(((irep > isub) ? (float)strlen(source) / isub* irep + 1 : isource) * sizeof(char));pc1 = result; /*为pc1依次复制结果串的每个字节作准备*/while (*source != NULL){/*为检查source与sub是否相等作准备,为pc2,pc3 赋初值*/pc2 = source;pc3 = sub;/* 出循环的(任一)条件是: *  *pc2 不等于 *pc3 (与子串不相等) *  pc2  到源串结尾 *  pc3  到源串结尾 (此时,检查了全部子串,source处与sub相等) *****************************************************/while (*pc2 == *pc3 &&*pc3!= NULL && *pc2 != NULL)pc2++, pc3++;/* 如果找到了子串,进行以下处理工作*/if (NULL == *pc3){pc3 = rep;/*将替代串追加到结果串*/while (*pc3 != NULL)*pc1++ = *pc3++;pc2--;source = pc2;/*   检查 source与sub相等的循环结束后, * pc2 对应的位置是在 sub 中串结束符处。该是源串中下一个位置。 * 将 source 指向其前面一个字符。 ***************************************************/}else /*如果没找到子串,下面复制source所指的字节到结果串*/*pc1++ = *source;source++; /* 将source向后移一个字符*/}*pc1 = NULL;return result;
}//以下为测试代码:int main()
{char s1[] = "abbccdfdcdbbdcd";char s2[] = "dcd";char s3[] = "12345";char *p = replace(s1, s2, s3);printf("source=%s\n",s1);puts(s1);printf("sub = %s\n",s2);puts(s2);printf("replace string = %s\n", p);char str1[] = "   究天人之际, 通古今之变, 成一家之说";char str2[] = "说";char str3[] = "言";char *strp = replace(str1, str2, str3);//printf("source=%s\n", str1);puts(str1);//printf("sub = %s\n", str2);puts(str2);printf("replace string = %s\n", strp);return 0;
}

第四种方案

//在s串中查找与s1相匹配的字符串,找到后用s2将s中与s1相配的串替换掉
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>void replace(char *s, char *s1, char *s2);int main(int argc, char *argv[]){char s[256], s1[256], s2[256];if (argc != 4){printf("Usage:%s 源串 查找串 替换串\n", argv[0]);return -1;}memset(s, sizeof(s), 0x00);memset(s1, sizeof(s1), 0x00);memset(s2, sizeof(s2), 0x00);strcpy(s, argv[1]);strcpy(s1, argv[2]);strcpy(s2, argv[3]);replace(s, s1, s2);printf("%s\n", s);
}void replace(char *s, char *s1, char *s2)
{char *p, *sp, *dp;int len, cnt;for (;;){if ((p = strstr(s, s1)) == NULL) return;len = strlen(s2) - strlen(s1);if (len){//查找串和替换串长度不相同,需移位动作     sp = p + strlen(s1);  //从sp所指位置移     dp = sp + len;  //移到dp所指位置     cnt = strlen(sp) + 1; //所要移动的长度     memmove(p + strlen(s1) + len, p + strlen(s1), cnt);}memcpy(p, s2, strlen(s2));}
}

思考

但不是很有时候会有问题,比如

后面的一个是另一个的字串时就会出错。其实通过第一次替换就成功了。

Without labor nothing prospers.
没有辛勤劳动,就不会有欣欣向荣的一切。

传智播客 C/C++学习笔记 字符串替换相关推荐

  1. 【传智播客】Libevent学习笔记(三):事件循环

    目录 00. 目录 01. event_base_loop函数 02. event_base_dispatch函数 03. event_base_loopexit函数 04. event_base_l ...

  2. 【传智播客】Libevent学习笔记(四):事件event

    目录 00. 目录 01. 事件概述 02. 创建事件 03. 事件的标志 04. 事件持久性 05. 超时事件 06. 信号事件 07. 设置不使用堆分配的事件 08. 事件的未决和非未决 09. ...

  3. 【传智播客】Libevent学习笔记(一):简介和安装

    目录 00. 目录 01. libevent简介 02. Libevent的好处 03. Libevent的安装和测试 04. Libevent成功案例 00. 目录 @ 01. libevent简介 ...

  4. 传智播客黑马Java学习笔记_day08_2

    设计模式:对问题行之有效的解决方式,一种思想,java24种 单例设计模式 解决问题:可以保证一个类的对象在内存中的唯一性 应用场景:多个程序使用同一个配置文件对象,就要保证配置文件的唯一性,配置文件 ...

  5. 传智播客黑马Java学习笔记_09

    在子类创建对象时,发现父类的构造方法也运行了,为什么呢? 在子类的构造函数中第一行有一个隐式语句super(); class Fu{Fu(){System.out.println("Fu i ...

  6. 传智播客黑马Java学习笔记_day05

    遍历数组 class Demo{public static void main(String args[]){int[] arry=new int[]{87,99,56};for(int x=0;x& ...

  7. 传智播客黑马Java学习笔记_day10_02

    对象的多态性 父类或者接口的引用指向子类对象 多态的好处 提高了代码的扩展性,前期的代码可以使用后期的内容 多态的弊端 前期的代码不能调用后期的特有内容 多态的前提 必须有关系:继承.实现 必须覆盖父 ...

  8. 传智播客 传智播客.NET视频学习课件

    传智播客 传智播客.NET视频学习课件 访问.NET网站了解更多课程详情 http://net.itcast.cn (小提示:为什么本书中超链接打不开?) 此套课件是伴随传智播客.net实况教学视频 ...

  9. 【传智播客郑州校区分享】在传智播客郑州校区学习倍感幸运

    小李是传智播客郑州校区的一名学员,他大学学的是土木工程,当初报这个专业是觉得毕业后比较好找工作,然而经历四年的学习后才发现很多事情并不是自己想象的那样,但是刚毕业的小李还是不得不去从事与专业相关的工作 ...

  10. 感谢传智播客+C#.Net学习之旅

    <C#.Net基础学习视频2014版>在本月中旬左右终于学习完了,终于学完了.                 自2015年暑期7月份开始学习C#.Net基础学习视频以来,直到本月才学习完 ...

最新文章

  1. 猪八戒网CI/CD最佳实践之路
  2. UVa197 - Cube(TLE)
  3. 实用正则表达式(实用篇)
  4. 1.Prometheus快速入门,Prometheus+node_exporter安装
  5. 如何将usb连接到远程计算机,远程服务器怎么共享usb
  6. leetcode 168. Excel表列名称(10进制转26进制)
  7. Linux C++线程池
  8. 优先队列默认是小顶堆吗_一分钟带你读懂什么是堆?
  9. Python+Opencv图像处理新手入门教程(一):介绍,安装与起步
  10. 小菜编程成长记(一 面试受挫——代码无错就是好?)
  11. 中国工业管理软件如何突围?
  12. 你的脑容量(字符串问题,小技巧)
  13. ms17010漏洞复现-2003
  14. c语言看门狗的作用,AT89S52单片机看门狗C语言程序
  15. 移动端开发旅游预约_套餐列表页面动态展示_套餐详情页面动态展示
  16. java生成pdf表格并插入图片
  17. TreeMap根据value排序遇到的问题及分析
  18. 一款高品质回音消除 模块 : F-23
  19. 去除XP桌面图标的阴影
  20. windows计算机锁屏的快捷键是什么,win7的锁屏快捷键是什么 win7锁屏快捷键介绍【图文】...

热门文章

  1. php curl 缓存请求_PHP异步非阻塞实现方法
  2. feign调用多个服务_SpringCloud服务间调用
  3. java 服务器时间 jvm_手动设置jvm时间改为第8时区的时间JVM虚拟机时区设置问题,java日期工具类各种解决不好使,很麻烦...
  4. python treeview控件使用详解_python绘图工具turtle库的使用详解
  5. html编辑器全角 半角转换,javascript实现全角与半角字符的转换
  6. mysql5建函数报1064错误_Mysql创建表过程中报1064错误
  7. Mysql批量添加数据
  8. 解决gitlab内存占用过多的问题
  9. webpack4.0配置记录(2) 1
  10. Mysql高性能总结