实现C字符串常用函数

//字符串长度
int StringLen(const char *str) {
	//用于记录有效字符的数量。
	int num = 0;
	//当前字符为有效字符时,递增指针指向一个字符,\0的值为0可终止循环体。
	while(*str++) ++num;
	return num;
}

//字符串比较
int StringCompare(const char *dst, const char *src) {
	//用于记录单个字符的比较结果
	int ret = 0;
	//源字符串中按顺序每一个字符与目标字符串中对应的字符相减,
	//如果为0代表一样,并且目标字符串没有达到末尾,那么将比较下一个字符
	while( !(ret = *src - *dst) && *dst) ++src, ++dst;
	return ret;
}

//字符串复制
char * StringCopy(char *dst, const char *src) {
	//记录目标字符串首地址
	char *last = dst;
	//循环将源字符串的每一个字符赋值于目标字符串对应的位置,后置自加指针指向,如果该字符为\0循环停止
	while(*dst++ = *src++);
	return last;
}

//字符串连接
char * StringConcat(char *dst, const char *src) {
	//记录目标字符串首地址
	char *last = dst;
	//将目标字符串指针移动到末尾\0,
	while(*dst)++dst;
	//利用复制功能将源字符添加到目标末尾。
	StringCopy(dst, src);
	return last;
}

//获取子串
char * SubString(const char *str, const char *sub) {
	//索引变量指针
	char *StrIndex = NULL;
	char *SubIndex = NULL;
	//循环目标字符串每次递增一个字符
	while(*str) {
		//每次循环重置索引指针
		StrIndex = (char*)str;
		SubIndex = (char*)sub;
		//循环比较字符,如果两个字符串都没有达到末尾,并且对应位置上的字符相同,那么比较下一个字符
		while(*StrIndex && *SubIndex && (*StrIndex == *SubIndex)) ++StrIndex, ++SubIndex ;
		//如果循环结束后当前索引指针指向为\0,说明其之前的内容相同。返回目标字符串当前位置。
		if(!*SubIndex) return (char*)str;

		++str;
	}
	return NULL;
}

//字符串反转
char* StringReverse(char* str) {
	//定义字符串头指针与尾指针
	char *end = str, *start = str;
	while(*end++);
	end -= 2; 
	//循环条件尾指针大于头指针
	while(end > start) {
		//使用异或交换头尾字符,并最后一次操作时进行后置自加。
		*start = *start ^ *end;
		*end = *start ^ *end;
		*start = *start++ ^ *end--;
	}
	return str;
}

//字符串切割
char * StringSplit ( char *string, const char *control )
{
	//利用静态成员只能被初始化一次的特性记录上一次被切割的位置
	static char * toKen = NULL; 
	//临时指针
	char *str = NULL;
	//切割标记字符串临时指针
	const char *ctrl = control;
	//定义一个32元素的1字节数组。高端的位运算,与位记录,提高程序运行效率,节省内存占用空间。
	char map[32] = {0,};
	//切割标记每1个字符前5个字节决定在该数组中的位置,
	//因为5个2进制最大数为31也就是包含0在内不同的32个数,对应数组的32个元素,
	//后3个字节用来决定元素中保存的数字,
	//为了保证元素内数字不会重复,使用2进制单个位来表示这个数的后3个字节。
	//因为3个2进制最大数为7,从0到7共8个数,而1个char类型正好8位。
	//通过*ctrl >> 3决定标记字符所在的数组位置,而每一个位置上的值绝对不会超过8种,即0到7的值,也就是3个二进制。
	//通过1 << (*ctrl & 7)与数组位置上的值与运算,将位值添加到数组元素中。
	//其实就相当于一个2维数组,用字符的前5位标引X坐标,用字符的后3位索引Y坐标。
	do {
		map[*ctrl >> 3] |= (1 << (*ctrl & 7));
	} while (*ctrl++);

	//判断是否是第二次切割
	if (string)
		str = string;
	else
		str = toKen;
	//检测数组中对应位置上对应位上的值是否为1,即判断该字符是否是要被切除的内容。
	while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )
		str++;
	//过滤掉切除的内容后记录当前的指针位置
	string = str;
	//找到下一个切割点,将其设置为\0后自加。
	for ( ; *str ; str++ )
		if ( map[*str >> 3] & (1 << (*str & 7)) ) {
			*str++ = '\0';
			break;
		}
	//记录切割点到静态区
	toKen = str;

	if ( string == str )
		return NULL;
	else
		return string;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值