传智播客 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.
没有辛勤劳动,就不会有欣欣向荣的一切。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值