前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言实现String字符串及其函数

C语言实现String字符串及其函数

作者头像
小锋学长生活大爆炸
发布2020-11-12 11:22:43
1.2K0
发布2020-11-12 11:22:43
举报
文章被收录于专栏:小锋学长生活大爆炸

供参考学习~

下载链接(没法更新的):https://download.csdn.net/download/sxf1061700625/13090575

stringUtil.h

代码语言:javascript
复制
#ifndef _STRINGUTIL_H
#define _STRINGUTIL_H

#define true  1
#define false 0
typedef char* String;
typedef char** Array_t;
typedef unsigned char Bool;

typedef struct
{
  char* (*addExtra)(char*, char*);
	char* (*add)(char*, char*);
	char* (*newString)(int, ...);
	void  (*delString)(char*);
	int   (*split)(char*, char*, Array_t*);
	int   (*splitExtra)(char*, char*, Array_t*);
	void  (*delArray)(Array_t, int);
	char* (*toUpper)(char*);
	char* (*toLower)(char*);
	Bool  (*startWith)(char*, char*);
	Bool  (*endWith)(char*, char*);
	char* (*join)(Array_t, int);
	char* (*strip)(char*, char*);
}STRINGUTIL;
extern STRINGUTIL StringUtil;


void stringUtilTest(void);


#endif

stringUtil.c

代码语言:javascript
复制
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "ctype.h"
#include "stdarg.h"
#include "stringUtil.h"

static char* addExtra(char* p1, char* p2);
static char* add(char* p1, char* p2);
static char* newString(int num, ...);
static void  delString(char* p);
static int   split(char* buff, char* separator, Array_t* result);
static int   splitExtra(char* buff, char* separator, Array_t* result);
static void  delArray(Array_t p, int n);
static char* toUpper(char* ptr);
static char* toLower(char* ptr);
static Bool  startWith(char* src, char* str);
static Bool  endWith(char* src, char* str);
static char* join(Array_t ptr, int n);
static char* strip(char* ptr, char* separator);


STRINGUTIL StringUtil = {.add=add,
             .addExtra=addExtra,
						 .newString=newString,
						 .delString=delString,
						 .split=split,
						 .splitExtra=splitExtra,
						 .delArray=delArray,
						 .toUpper=toUpper,
						 .toLower=toLower,
						 .startWith=startWith,
						 .endWith=endWith,
						 .join=join,
						 .strip=strip
						};


/**
 * @description: 字符串合并
 * @param {p1} 字符串1
 * @param {p2} 字符串2
 * @return {*} 合并后的字符串指针p1
 * @attention 会释放p1,所以调用时等号左边要有,不能省略,否则用的是已经释放的旧地址。如:str = stringUtil.add(p1,p2)
 */
static char* addExtra(char* p1, char* p2)
{
	char* ptr = NULL;
	ptr = (char*)realloc(p1, strlen(p1)+strlen(p2)+1);
	if (ptr != NULL) {
		strcat(ptr, p2);
	}
	return ptr;
}

/**
 * @description: 字符串合并
 * @param {p1} 字符串1
 * @param {p2} 字符串2
 * @return {*} 合并后的字符串指针p1
 * @attention 会创建一个新的字符串返回
 */
static char* add(char* p1, char* p2)
{
	char* ptr = NULL;
	ptr = (char*)calloc(strlen(p1)+strlen(p2)+1, 1);
	if (ptr != NULL) {
		strcat(ptr, p1);
		strcat(ptr, p2);
	}
	return ptr;
}

/**
 * @description: 创建字符串
 * @param {num} 字符串数组的个数
 * @param {...} 多个字符串数组
 * @return {*} 创建完的字符串指针
 * @attention 需要调用delString()手动释放ptr
 */
static char* newString(int num, ...)
{
	char *arg = NULL;
	va_list ap;
	int length = 0;
	va_start(ap, num);
	for (int i = 0; i < num; i++) {
		arg = va_arg(ap, char*);
		length += strlen(arg);
	}
	// va_end(ap);
	char* ptr = (char*)calloc(length+1, sizeof(char));
	if (ptr != NULL) {
		va_start(ap, num);
		for (int i = 0; i < num; i++) {
			arg = va_arg(ap, char*);
			strcat(ptr, arg);
		}
		va_end(ap);
	}else {
		printf("malloc failed\r\n");
	}
	return ptr;
}


/**
 * @description: 释放一维指针的内存
 * @param {p} 一维指针
 * @return {*} 无
 */
static void delString(char* p)
{
	free(p);
	p = NULL;
}

/**
 * @description: 释放二维指针的内存
 * @param {p} 二维指针
 * @param {n} 第一维的数量
 * @return {*} 无
 * @attention 使用本函数可释放调用split()函数后的二维指针的内存
 */
static void delArray(Array_t p, int n)
{
	for(int i=0; i<n; i++) {
		free(*(p+i));
	}
	free(p);
	p = NULL;
}

/**
 * @description: 分割字符串
 * @param {buff} 待分割的字符串指针
 * @param {separator} 分隔符
 * @param {result} 分割后的字符串数组
 * @return {*} 分割后的字符串数组的第一维的数量
 * @attention 会改变原字符串,需要调用delArray()手动释放result
 */
static int split(char* buff, char* separator, Array_t* result)
{
	int max = 4;
	int index = 0;
	*result = (Array_t)calloc(max, sizeof(char*));
	
	char *token;
	/* 获取第一个子字符串 */
	token = strtok(buff, separator);
	/* 继续获取其他的子字符串 */
	while( token != NULL ) {
		// printf( "%s\n", token);
		if(index == max) {
			max *= 2;
			*result = (Array_t)realloc(*result, max*sizeof(char*));
			if(*result == NULL) {
				printf("realloc failed\r\n");
				return 0;
			}else {
				// printf("realloc success\r\n");
			}
		}
		*(*result+index) = (char*)calloc(strlen(token)+1, sizeof(char));
		strcpy(*(*result+index), token);
		index ++;
		token = strtok(NULL, separator);
	}
	return index;
}

/**
 * @description: 分割字符串
 * @param {buff} 待分割的字符串指针
 * @param {separator} 分隔符
 * @param {result} 分割后的字符串数组
 * @return {*} 分割后的字符串数组的第一维的数量
 * @attention 不会改变原字符串,需要调用delArray()手动释放result
 */
static int splitExtra(char* buff, char* separator, Array_t* result)
{
	int max = 4;
	int index = 0;
	char *prev = buff;
	char *token;

	*result = (Array_t)calloc(max, sizeof(char*));
	/* 获取第一个子字符串 */
	token = strstr(buff, separator);
	/* 继续获取其他的子字符串 */
	while( token != NULL ) {
		// printf( "%s\n", token);
		if(index == max) {
			max *= 2;
			*result = (Array_t)realloc(*result, max*sizeof(char*));
			if(*result == NULL) {
				printf("realloc failed\r\n");
				return 0;
			}else {
				// printf("realloc success\r\n");
			}
		}
		*(*result+index) = (char*)calloc(token-prev+1, sizeof(char));
		if (*(*result+index) == NULL) {
			printf("calloc failed\r\n");
		}
		memcpy(*(*result+index), prev, token-prev);
		prev = token+strlen(separator);
		index ++;
		token = strstr(prev, separator);
	}
	/* 将最后部分加入 */
	if(index == max) {
		max += 1;
		*result = (Array_t)realloc(*result, max*sizeof(char*));
		if(*result == NULL) {
			printf("realloc failed\r\n");
			return 0;
		}else {
			// printf("realloc success\r\n");
		}
	}
	int remain = strlen(buff)-(prev-buff);
	*(*result+index) = (char*)calloc(remain+1, sizeof(char));
	if (*(*result+index) == NULL) {
		printf("calloc failed\r\n");
	}
	memcpy(*(*result+index), prev, remain);
	index ++;

	return index;
}

/**
 * @description: 字符串大写
 * @param {ptr} 原字符串
 * @return {*} 大写后得字符串
 * @attention 会改变原字符串
 */
static char* toUpper(char* ptr)
{
	char *orign = ptr;
    for (; *ptr != '\0'; ptr++) {
		*ptr = toupper(*ptr);
	}
    return orign;
}

/**
 * @description: 字符串小写
 * @param {ptr} 原字符串
 * @return {*} 小写后得字符串
 * @attention 会改变原字符串
 */
static char* toLower(char* ptr)
{
	char *orign = ptr;
    for (; *ptr != '\0'; ptr++) {
		*ptr = tolower(*ptr);
	}
    return orign;
}

/**
 * @description: 是否以指定子字符串开头
 * @param {src} 待比较的字符串
 * @param {str} 指定的子字符串
 * @return {*} true/false
 */
static Bool startWith(char* src, char* str)
{
	if (strlen(src) < strlen(str)) {
		return false;
	}
	for (int i = 0; i < strlen(str); i++) {
		if (src[i] != str[i]) {
			return false;
		}
	}
	return true;
}

/**
 * @description: 是否以指定子字符串结尾
 * @param {src} 待比较的字符串
 * @param {str} 指定的子字符串
 * @return {*} true/false
 */
static Bool endWith(char* src, char* str)
{
	if (strlen(src) < strlen(str)) {
		return false;
	}
	char* ptr = src+(strlen(src)-strlen(str));
	for (int i = 0; i < strlen(str); i++) {
		if (ptr[i] != str[i]) {
			return false;
		}
	}
	return true;
}

/**
 * @description: 将字符串数组合并为一个字符串
 * @param {ptr} 字符串数组
 * @param {n} 数组第一维的数量
 * @return {*} 合并后的字符串
 * @attention 需要调用delString()手动释放buff
 */
static char* join(Array_t ptr, int n)
{
	int length = 0;
	for (int i = 0; i < n; i++) {
		length += strlen(*(ptr+i));
	}
	char* buff = NULL;
	buff = (char*)calloc(length+1, sizeof(char));
	if (buff)
	{
		for (int i = 0; i < n; i++) {
			strcat(buff, *(ptr+i));
		}
	}
	return buff;
}

/**
 * @description: 移除字符串中指定的子字符串
 * @param {ptr} 原字符串指针
 * @param {ptr} 指定的子字符串指针
 * @return {*} 移除后的字符串指针,会改变原字符串
 */
static char* strip(char* ptr, char* separator)
{
	Array_t res_arr;
	int cnt = splitExtra(ptr, separator, &res_arr);
	char* res_str = join(res_arr, cnt);
	strcpy(ptr, res_str);
	delArray(res_arr, cnt);
	delString(res_str);
	return ptr;
}


void stringUtilTest()
{
	String str = StringUtil.newString(2, "ab", "cd");
	printf("1. new String (abc): %s\r\n", str);

	str = StringUtil.add(str, ",e,f,g,h");
	printf("2. add String (,e,f,g,h): %s\r\n", str);

	Array_t res;
	int cnt = StringUtil.splitExtra(str, ",", &res);
	printf("3. split String: ");
	for (int i = 0; i < cnt; i++) {
		printf("[%d]: %s  ", i, res[i]);
	}
	printf("\r\n");

	StringUtil.toUpper(str);
	printf("4. upper String: %s\r\n", str);

	StringUtil.toLower(str);
	printf("5. lower String: %s\r\n", str);

	Bool check = StringUtil.startWith(str, "abc");
	printf("6. startWith (abc): %d\r\n", check);

	check = StringUtil.endWith(str, ",h");
	printf("7. endWith (,h): %d\r\n", check);

	String joinstr = StringUtil.join(res, cnt);
	printf("8. join String: %s\r\n", joinstr);

	StringUtil.strip(str, ",");
	printf("9. strip String: %s\r\n", str);

	StringUtil.delString(joinstr);
	StringUtil.delArray(res, cnt);
	StringUtil.delString(str);
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/11/05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • stringUtil.h
  • stringUtil.c
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档