传智播客 C/C++学习笔记 字符串替换
目录
方案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++学习笔记 字符串替换相关推荐
- 【传智播客】Libevent学习笔记(三):事件循环
目录 00. 目录 01. event_base_loop函数 02. event_base_dispatch函数 03. event_base_loopexit函数 04. event_base_l ...
- 【传智播客】Libevent学习笔记(四):事件event
目录 00. 目录 01. 事件概述 02. 创建事件 03. 事件的标志 04. 事件持久性 05. 超时事件 06. 信号事件 07. 设置不使用堆分配的事件 08. 事件的未决和非未决 09. ...
- 【传智播客】Libevent学习笔记(一):简介和安装
目录 00. 目录 01. libevent简介 02. Libevent的好处 03. Libevent的安装和测试 04. Libevent成功案例 00. 目录 @ 01. libevent简介 ...
- 传智播客黑马Java学习笔记_day08_2
设计模式:对问题行之有效的解决方式,一种思想,java24种 单例设计模式 解决问题:可以保证一个类的对象在内存中的唯一性 应用场景:多个程序使用同一个配置文件对象,就要保证配置文件的唯一性,配置文件 ...
- 传智播客黑马Java学习笔记_09
在子类创建对象时,发现父类的构造方法也运行了,为什么呢? 在子类的构造函数中第一行有一个隐式语句super(); class Fu{Fu(){System.out.println("Fu i ...
- 传智播客黑马Java学习笔记_day05
遍历数组 class Demo{public static void main(String args[]){int[] arry=new int[]{87,99,56};for(int x=0;x& ...
- 传智播客黑马Java学习笔记_day10_02
对象的多态性 父类或者接口的引用指向子类对象 多态的好处 提高了代码的扩展性,前期的代码可以使用后期的内容 多态的弊端 前期的代码不能调用后期的特有内容 多态的前提 必须有关系:继承.实现 必须覆盖父 ...
- 传智播客 传智播客.NET视频学习课件
传智播客 传智播客.NET视频学习课件 访问.NET网站了解更多课程详情 http://net.itcast.cn (小提示:为什么本书中超链接打不开?) 此套课件是伴随传智播客.net实况教学视频 ...
- 【传智播客郑州校区分享】在传智播客郑州校区学习倍感幸运
小李是传智播客郑州校区的一名学员,他大学学的是土木工程,当初报这个专业是觉得毕业后比较好找工作,然而经历四年的学习后才发现很多事情并不是自己想象的那样,但是刚毕业的小李还是不得不去从事与专业相关的工作 ...
- 感谢传智播客+C#.Net学习之旅
<C#.Net基础学习视频2014版>在本月中旬左右终于学习完了,终于学完了. 自2015年暑期7月份开始学习C#.Net基础学习视频以来,直到本月才学习完 ...
最新文章
- 猪八戒网CI/CD最佳实践之路
- UVa197 - Cube(TLE)
- 实用正则表达式(实用篇)
- 1.Prometheus快速入门,Prometheus+node_exporter安装
- 如何将usb连接到远程计算机,远程服务器怎么共享usb
- leetcode 168. Excel表列名称(10进制转26进制)
- Linux C++线程池
- 优先队列默认是小顶堆吗_一分钟带你读懂什么是堆?
- Python+Opencv图像处理新手入门教程(一):介绍,安装与起步
- 小菜编程成长记(一 面试受挫——代码无错就是好?)
- 中国工业管理软件如何突围?
- 你的脑容量(字符串问题,小技巧)
- ms17010漏洞复现-2003
- c语言看门狗的作用,AT89S52单片机看门狗C语言程序
- 移动端开发旅游预约_套餐列表页面动态展示_套餐详情页面动态展示
- java生成pdf表格并插入图片
- TreeMap根据value排序遇到的问题及分析
- 一款高品质回音消除 模块 : F-23
- 去除XP桌面图标的阴影
- windows计算机锁屏的快捷键是什么,win7的锁屏快捷键是什么 win7锁屏快捷键介绍【图文】...
热门文章
- php curl 缓存请求_PHP异步非阻塞实现方法
- feign调用多个服务_SpringCloud服务间调用
- java 服务器时间 jvm_手动设置jvm时间改为第8时区的时间JVM虚拟机时区设置问题,java日期工具类各种解决不好使,很麻烦...
- python treeview控件使用详解_python绘图工具turtle库的使用详解
- html编辑器全角 半角转换,javascript实现全角与半角字符的转换
- mysql5建函数报1064错误_Mysql创建表过程中报1064错误
- Mysql批量添加数据
- 解决gitlab内存占用过多的问题
- webpack4.0配置记录(2) 1
- Mysql高性能总结