C标准库没提供的助手函数:字符串替换

/************************ (C) COPYRIGHT 2015 Gizwits ****************************
 * @file              : strrpl.h
 * @author            : William Yip
 * @date              : 18 Dec 2015
 * @version           : 1.0
 * @brief             : 连接、增值、开放、中立、安全、自有、自由、生态
 ********************************************************************************
 * History:
 ********************************************************************************
 THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH
 CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A
 RESULT, GIZWITS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
 CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT OF
 SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
 CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
 *******************************************************************************/


#ifndef _GIZWITS_STRRPL_H_
#define _GIZWITS_STRRPL_H_


#include <string.h>
#include <stdlib.h>
#include <stdio.h>


// #define GIZWITS_STRRPL_EXAMPLE


/**
 * @desc C助手函数,字符串替换
 * @param str 源字符串
 * @param token 将被替换的内容
 * @param replacement 要替换成的新内容
 * @memo 如果想运行示例,打开GIZWITS_STRRPL_EXAMPLE预定义开关进行编译,具体示例代码在main() @ strrpl.cpp中
 */
char * strrpl(const char * str, const char * token, const char * replacement);


#endif // _GIZWITS_STRRPL_H_

/************************ (C) COPYRIGHT 2015 Gizwits ****************************
 * @file              : strrpl.c
 * @author            : William Yip
 * @date              : 18 Dec 2015
 * @version           : 1.0
 * @brief             : 连接、增值、开放、中立、安全、自有、自由、生态
 ********************************************************************************
 * History:
 ********************************************************************************
 THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH
 CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A
 RESULT, GIZWITS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
 CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT OF
 SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
 CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
 *******************************************************************************/

#include "strrpl.h"

#ifdef GIZWITS_STRRPL_EXAMPLE
void main()
{
	char * json = "{\"data\":[{\"product_key\":\"14ea605e1b7b43228494400e340fc7bb\",\"device_sn\":\"accf23796032\",\"uid\":\"3b2a09ea7a14430ba7938ddb93140a2e\",\"ts\":1450349681,\"attrs\":{\"Down\":false,\"Right\":false,\"speed\":\"0\",\"Up\":false,\"Left\":false}}]}";
	char * token = "\"";
	char * replacement = "\\\"";
	char * result = strrpl(json, token, replacement);
	printf("\n%s\n\n", result);
	free(result);
}
#endif // GIZWITS_STRRPL_EXAMPLE

char * strrpl(const char * str, const char * token, const char * replacement)
{
	int lenToken = strlen(token);
	int lenReplacement = strlen(replacement);
	int lenResult = 0;

	char * begin = NULL;
	char * end = NULL;
	int count = 0;

	char * output = NULL;
	char * tmp = NULL;
	int len = 0;

	int i = 0;

	// 输入检查:防止参数空指针
	if (!str || !token || !replacement)
	{
		fprintf(stderr, "%s(), NULL parameter is not allowed", __func__);
		return NULL;
	}

	// 先搜一遍:找有多少个可替换先
	end = begin = (char *) str;
	count = 0;
	for ( end = strstr(str, "\"");
		NULL != end;
		end = strstr(begin, "\"") )
	{
		count++;
		begin = end + lenToken;
	}

	// 预分配替换后的目标字符串缓冲
	lenResult = strlen(str) + count * (lenReplacement - lenToken) + 1;
	output = malloc(lenResult);

	// 真正进行替换
	end = begin = (char *) str;
	tmp = output;
	for ( end = strstr(str, "\"");
		NULL != end;
		end = strstr(begin, "\"") )
	{
		len = end - begin;
		memcpy(tmp, begin, len); tmp += len;
		// 目标字符串,游标移位
		for (i=0; i<lenReplacement; i++)
		{
			*tmp = replacement[i];
			tmp++;
		}
		// 源字符串,游标移位
		begin = end + lenToken;
	}

	// 最后一个替换后剩余的结尾(或者没有替换可进行时,就直接拷贝整个源字符串)
	len = strlen(str) - (begin - str);
	if (len > 0)
		memcpy(tmp, begin, len);

	// 目标字符串加终止符,确保不越界
	output[lenResult - 1] = '\0';

	return output;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值