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

2020-11-12 11:22:43 浏览数 (1)

供参考学习~

下载链接(没法更新的):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 failedrn");
	}
	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( "%sn", token);
		if(index == max) {
			max *= 2;
			*result = (Array_t)realloc(*result, max*sizeof(char*));
			if(*result == NULL) {
				printf("realloc failedrn");
				return 0;
			}else {
				// printf("realloc successrn");
			}
		}
		*(*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( "%sn", token);
		if(index == max) {
			max *= 2;
			*result = (Array_t)realloc(*result, max*sizeof(char*));
			if(*result == NULL) {
				printf("realloc failedrn");
				return 0;
			}else {
				// printf("realloc successrn");
			}
		}
		*(*result index) = (char*)calloc(token-prev 1, sizeof(char));
		if (*(*result index) == NULL) {
			printf("calloc failedrn");
		}
		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 failedrn");
			return 0;
		}else {
			// printf("realloc successrn");
		}
	}
	int remain = strlen(buff)-(prev-buff);
	*(*result index) = (char*)calloc(remain 1, sizeof(char));
	if (*(*result index) == NULL) {
		printf("calloc failedrn");
	}
	memcpy(*(*result index), prev, remain);
	index   ;

	return index;
}

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

/**
 * @description: 字符串小写
 * @param {ptr} 原字符串
 * @return {*} 小写后得字符串
 * @attention 会改变原字符串
 */
static char* toLower(char* ptr)
{
	char *orign = ptr;
    for (; *ptr != ''; 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): %srn", str);

	str = StringUtil.add(str, ",e,f,g,h");
	printf("2. add String (,e,f,g,h): %srn", 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("rn");

	StringUtil.toUpper(str);
	printf("4. upper String: %srn", str);

	StringUtil.toLower(str);
	printf("5. lower String: %srn", str);

	Bool check = StringUtil.startWith(str, "abc");
	printf("6. startWith (abc): %drn", check);

	check = StringUtil.endWith(str, ",h");
	printf("7. endWith (,h): %drn", check);

	String joinstr = StringUtil.join(res, cnt);
	printf("8. join String: %srn", joinstr);

	StringUtil.strip(str, ",");
	printf("9. strip String: %srn", str);

	StringUtil.delString(joinstr);
	StringUtil.delArray(res, cnt);
	StringUtil.delString(str);
}

0 人点赞