字符串的封装

//编译环境VS2013

strStr.h
#define  _CRT_SECURE_NO_WARNINGS

//字符串封装,需要库函数
//不需要库函数,我现在完成的就是自己实现库函数

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

struct CString
{
	char *p;<span style="white-space:pre">	</span>//保存字符串首地址
	int realLength;<span style="white-space:pre">	</span>//实际长度
};
typedef struct CString myString; //全局变量

//主要实现的功能概述如下:
//字符串,初始化,打印,
//查找,查找字符,查找字符串
//尾部增加,(字符,字符串)
//删除(字符,字符串),
//任意位置增加(字符,字符串)
//修改字符串,(字符,字符串替换)


void initStr(myString *string); <span style="white-space:pre">			</span>//原封不动初始化
void initWithLength(myString *string, int length);<span style="white-space:pre">	</span>//开辟长度,内存清零
void initWithString(myString *string, char *copyString);//初始化,并拷贝字符串
void printStr(myString *string); //打印
void backAddChar(myString *string, char *ch);<span style="white-space:pre">		</span> //尾部插入字符
void backAddString(myString *string, char *str);<span style="white-space:pre">	</span>//尾部掺入字符串
void run(myString *string);
//以下两个查找函数 ,仅仅是找到了第一个匹配的字符,还要完成所有匹配的字符
//完成这个工作仅仅需要续断循环查找即可
char *findFirstChar(myString *string, char ch);<span style="white-space:pre">		</span>//返回第一个匹配的字符
char *findFirstString(myString *string, char str);
int deleteFirstChar(myString *string, char ch);
int deleteFirstString(myString *string, char *str);

void addChar(myString *string, char *ch, char *pos);<span style="white-space:pre">	</span> //任意位置增加字符
void addString(myString *string, char *str, char *pos);<span style="white-space:pre">	</span>//任意位置增加字符串

void changeFirstChar(myString *string, const char oldChar, const newChar);
void changeFirstString(myString *string, char * const oldString, char *const newString);


//strStr.c  主要函数文件

#include"strStr.h"

int myStrLen(char *p) //strlen()
{
	if (p == NULL)
	{
		return -1; //失败
	}
	int length = 0;
	while (*p != '\0')
	{
		length++;
		p++;
	}
	return length;
}

//完全可以替代strcpy函数。
char *myStrcpy(char *dest, const char *source) //限制拷贝的时候修改内容
{
	if (dest == NULL || source == NULL)
	{
		return NULL;
	}
	char *destback = dest;
	while (*source != '\0')
	{
		*dest = *source; //赋值

		source++;
		dest++;//指针不断向前
	}
	*dest = '\0';
	return destback;
}
char *myStrcat(char *dest, const char *source)
{
	if (dest == NULL || source == NULL)
	{
		return NULL;
	}
	else
	{
		char *destbak = dest; //保留dest的地址
		while (*dest != '\0')
		{
			dest++;//指针移动,直到\0
		}
		while (*source != '\0')
		{
			*dest = *source;
			dest++;
			source++;
		}
		*dest = '\0';
		return destbak;
	}
}
char *myStrchr(const char *dest, const char ch) //找寻一个字符
{
	if (dest == NULL)
	{
		return NULL;
	}
	while (*dest != '\0')
	{
		if (*dest == ch)
		{
			return dest;//找到ch,返回地址
		}
		dest++;
	}
	return NULL; //找到最后都没有找到
}

char *myStrstr(const char * const dest, const char * const findStr)
{
	if (dest == NULL || findStr == NULL)
	{
		return NULL;
	}

	char *destbak = dest;//备份dest
	char *p = NULL; //保存找到的地址

	while (*destbak != '\0')
	{
		int flag = 1;//假设相等
		char *findStrbak = findStr; //备份findStr;
		char *nowdestbak = destbak;

		while (*findStrbak != '\0')
		{
			if (*nowdestbak != '\0')//判断被查找字符串是否结束
			{
				//有一个不相等,就不相等
				if (*findStrbak != *nowdestbak)
				{
					flag = 0;//不相等
				}
				nowdestbak++;
				findStrbak++;
			}
			else
			{
				flag = 0; //设置标识
				break;
			}
		}
		if (flag == 1)//找到了
		{
			p = destbak;//找到位置首地址
			return p; //返回找到的字符串的地址。
		}
		destbak++;
	}
	return NULL; //遍历完成之后没有任何效果则返回空。
}



void initStr(myString *string) //原封不动初始化
{
	string->p = NULL;
	string->realLength = 0;
}
void initWithLength(myString *string, int length)//开辟长度,内存清零
{
	//string->p = (char *)malloc(sizeof(char)*length);//分配内存不清零
	string->p = (char *)calloc(length, sizeof(char));//分配内存并清零
	string->realLength = length;
}
void initWithString(myString *string, char *copyString)//初始化,并拷贝字符串
{
	int length = strlen(copyString);//获取字符串长度
	string->p = (char *)calloc(length + 1, sizeof(char));
	myStrcpy(string->p, copyString);//拷贝字符串
	//这里不需要考虑末尾字符串为\0的问题,因为一开始就全清零了
	string->realLength = length + 1; //设置字符串长度
}
void backAddChar(myString *string, char *ch) //尾部插入字符
{
	//strlen()函数不会计算\0.
	if (strlen(string->p) + 1 == string->realLength)//意味着满了
	{
		//重新分配内存
		string->p = realloc(string->p, string->realLength + 1);
		string->realLength += 1;
		string->p[string->realLength - 2] = ch;
		string->p[string->realLength - 1] = '\0';
		//末尾加0 结束
	}
	else
	{
		int nowLength = myStrLen(string->p);
		string->p[nowLength] = ch;
		string->p[nowLength + 1] = '\0';
	}
	
}
void backAddString(myString *string, char *str)//尾部掺入字符串
{
	int nowmyStringLength = myStrLen(string->p);//获取当前长度
	int addStringLength = myStrLen(str);//要增加的长度

	//如果 当前长度+要增加的长度+'\0'的长度 大于 原来字符串额实际长度
	if (nowmyStringLength + addStringLength + 1 > string->realLength)
	{
		//判断是否越界
		int needAddLength = nowmyStringLength + addStringLength + 1 - (string->realLength);
		//需要增加的程度等于将要加入的字符串程长度+1
		string->p = (char *)realloc(string->p, string->realLength + needAddLength);
		myStrcat(string->p, str);
		string->realLength += needAddLength; //改变字符串实际长度
	}
	else
	{
		myStrcat(string->p, str);
	}
}

void printStr(myString *string) //打印
{
	printf("\n string=%s", string->p);
}

void run(myString *string)
{
	system(string->p);
}

char *findFirstChar(myString *string, char ch)
{
	char *p = myStrchr(string->p, ch);
	return p;
}
char *findFirstString(myString *string, char *str)
{
	char *pres = myStrstr(string->p, str);
	return pres;
}

int deleteFirstChar(myString *string, const char ch)
{
	char *p = myStrchr(string->p, ch);//查找
	if (p == NULL)
	{
		return 0;
	}
	else
	{
		char *pnext = p + 1;
		while (*pnext != '\0')
		{
			*p = *pnext;
			p++;
			pnext++;//删除的元素后面的每一个元素都前移一位
		}
		*p = '\0';
		return 1;
		//一开始我有一个问题就是,当pnext='\0'.也就是整个dest中
		//只有一个字符,且这个字符刚好是要删除的字符,那么while (*pnext != '\0')
		//
	}
}
int deleteFirstString(myString *string, char * const str)
{
	char *pres = myStrstr(string->p, str);
	if (pres == NULL)
	{
		return 0;//删除失败
	}
	else
	{
		int length = myStrLen(str); //求字符串长度
		char *pnext = pres + length; //下一个字符串
		while (*pnext != '\0')
		{
			*pres = *pnext; //将从pres到pres+length长度之间的字符串删除
			pres++;
			pnext++;
		}
		*pres = '\0';
		return 1; //删除成功
	}
}

void addChar(myString *string, char *ch, char *pos) //任意位置增加字符
{
	if (pos == NULL || string == NULL)
	{
		return;
	}
	if (myStrLen(string->p) + 1 == string->realLength)//意味着满了
	{
		//空间满了之后需要重新申请内存
		string->p = (char *)realloc(string->p, string->realLength + 1);
		//申请了内存之后,字符的实际长度就加1
		string->realLength += 1;
		//实际长度增加了之后开始移动,把要插入的位置腾出来

		int nowLength = myStrLen(string->p);//求出当前总长度
		int moveLength = myStrLen(pos);//要移动的长度,从插入位置pos一直到结尾

		for (int i = nowLength; i > nowLength - moveLength; i--)
		{
			string->p[i] = string->p[i - 1];//后移一位

		}
		//移动完成之后,插入位置腾出来了,现在插入字符
		string->p[nowLength - moveLength] = ch;//插入
		//插入之后将字符处啊末尾加上'\0'
		string->p[nowLength + 1] = '\0';
	}
	else //没有满的情况,也就是不用申请内存
	{
		int nowLength = myStrLen(string->p);//求出当前总长度
		int moveLength = myStrLen(pos);//要移动的长度,从插入位置pos一直到结尾

		for (int i = nowLength; i > nowLength - moveLength; i--)
		{
			string->p[i] = string->p[i - 1];//后移一位

		}
		//移动完成之后,插入位置腾出来了,现在插入字符
		string->p[nowLength - moveLength] = ch;//插入
		//插入之后将字符处啊末尾加上'\0'
		string->p[nowLength + 1] = '\0';
	}
}

void addString(myString *string, char *str, char *pos)//任意位置增加字符串
{
	if (pos == NULL || string == NULL)
	{
		return;
	}

	int nowmyStringLength = myStrLen(string->p);//获取当前长度
	int addStringLength = myStrLen(str);//要增加的长度

	//如果 当前长度+要增加的长度+'\0'的长度 大于 原来字符串额实际长度
	if (nowmyStringLength + addStringLength + 1 > string->realLength)
	{
		//判断是否越界
		int needAddLength = nowmyStringLength + addStringLength + 1 - (string->realLength);
		//需要增加的程度等于将要加入的字符串程长度+1
		string->p = (char *)realloc(string->p, string->realLength + needAddLength);
		string->realLength += needAddLength; //改变字符串实际长度

		//先移动,再拷贝,这与在尾部家字符串是不同的
		int nowLength = myStrLen(string->p);//求出当前总长度
		int moveLength = myStrLen(pos);//要移动的长度,从插入位置pos一直到结尾
		int insertLength = myStrLen(str);//求出要插入的字符串的长度

		for (int i = nowLength; i >= nowLength - moveLength; i--)
		{
			string->p[i+insertLength] = string->p[i];//后移一位

		}
		//移动完成之后,插入位置腾出来了,现在插入字符
		//由于插入的是字符串所以还需要一个循环
		for (int j = 0; j < insertLength; j++)
		{
			string->p[nowLength - moveLength + j] = str[j];//插入
		}
	}
	
	else//字符串没有满,也就是存储的字符串的长度小于实际长度
	{
		//先移动,再拷贝,这与在尾部家字符串是不同的
		int nowLength = myStrLen(string->p);//求出当前总长度
		int moveLength = myStrLen(pos);//要移动的长度,从插入位置pos一直到结尾
		int insertLength = myStrLen(str);//求出要插入的字符串的长度

		for (int i = nowLength; i > nowLength - moveLength; i--)
		{
			string->p[i + insertLength] = string->p[i];//后移一位

		}
		//移动完成之后,插入位置腾出来了,现在插入字符
		//由于插入的是字符串所以还需要一个循环
		for (int j = 0; j < insertLength; j++)
		{
			string->p[nowLength - moveLength + j] = str[j];//插入
		}
	} 
}

void changeFirstChar(myString *string, const char oldChar, const newChar)
{
	char *pstr = string->p;
	while (*pstr != '\0')
	{
		if (*pstr == oldChar)
		{
			*pstr = newChar;
			return; //如果要查询所有的oldChar则不需要return。
		}
		pstr++;
	}
}
void changeFirstString(myString *string, char * const oldString, char *const newString)
{
	char *pfind = findFirstString(string, oldString); //找到要修改的字符串
	if (pfind != NULL)
	{
		deleteFirstString(string, oldString); //删除
		addString(string, newString, pfind);//插入。
	}
}

//main.c  测试文件

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

void main()
{
	myString string1;

	//字符串初始化
	initWithString(&string1, "notepad");
	
	//backAddString(&string1, "pad");
	printStr(&string1);
	
	//查找第一个匹配的字符测试
	/*char *strp = findFirstChar(&string1, 'a');
	*strp = 'A';
	printf("%c\n", *strp);*/


	//查找第一个匹配的字符串
	//char *strp = findFirstString(&string1, "ad");
	//printf("%c\n", *strp);

	//查找第一个匹配的字符串,找不到的情况返回空。
	/*char *strp = findFirstString(&string1, "addd");
	if (strp != NULL)
	{
	*strp = 'X';

	}*/
	//printStr(&string1);

	删除字符测试
	//deleteFirstChar(&string1, 'n');
	//printStr(&string1);

	删除字符串测试
	//int num = deleteFirstString(&string1, "padf");
	//printStr(&string1);
	//if (num == 0)
	//{
	//	printf("\n删除失败\n");
	//}
	//else
	//{
	//	printf("删除成功\n");
	//}


	任意位置插入字符测试
	首先找到要插入的位置
	//char *p = findFirstChar(&string1, 't');
	//if (p != NULL)
	//{
	//	addChar(&string1, 'w', p);
	//}
	//printStr(&string1);


	任意位置插入字符串测试
	//backAddString(&string1, "notepad");
	//printStr(&string1);

	//char *p = findFirstChar(&string1, 't');
	printf("%s", p);
	//if (p != NULL)
	//{
	//	//printf("test\n");
	//	addString(&string1, "12345", p);
	//	//printf("%s\n", string1);
	//}
	addString(&string1, "1345", p);
	//printStr(&string1);

	替换字符 测试
	//changeFirstChar(&string1, 'p', 'A');
	//printStr(&string1);

	//替换字符串测试
	//backAddString(&string1, "notepad");
	//changeFirstString(&string1, "pad", "I Love C++!!");
	//printStr(&string1);

	//循环改变oldString
	backAddString(&string1, "notepadnotepadnotepadnotepad");
	printStr(&string1);
	while(findFirstString(&string1, "notepad"))
	{
		changeFirstString(&string1, "notepad", "123456789");
	}
	printStr(&string1);


	//run(&string1);  //执行指令

	system("pause");
}


  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值