/**********************************mystring.h*************************************/
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
using namespace std;
/*代码除创建的临时buf外,其他全部为深拷贝*/
class mystring
{
public:
friend ostream & operator <<(ostream &,const mystring & myTT); //重载输出流
friend istream & operator >>(istream &, mystring & MyTT); //重载输入流
public:
mystring();
mystring(char *p);
mystring(const mystring & str2); //重写,避免浅拷贝
~mystring();
public:
mystring & operator=(char *p); //重载= 实现 str1="asdas"; //str1为对象,下面同义
mystring & operator=(const mystring & mystr); //重写= 实现 str1=str2 深拷贝
mystring & operator+=(const mystring& mystr); //重载+= 实现 str1+=str2;
mystring & operator+=(char *p); //重载+= 实现 str1+="sdas";
static int mystrcmp(const mystring *str1, const mystring *str2); //比较两对象,相同返回0,否则: 若str1.size>str2.size 返回1,反之返回-1,
//长度相等,判断第一个不同的字母
char &operator [](int n); //重载[] 便于输出
public:
char * srea(char *p); //查找,存在返回出现首字符地址,不存在返回nullptr
void Insert(char *p, char *key); //插入,默认为p后面插入
void Append(char *key); //尾部插入
void StartInsert(char *key); //头部插入
void del(char *p); //删除 首个出现的p
void delAll(char *p); //删除所有的 p
void exchang(char *p, char *key); //替换 将首个出现的p替换为key
void exchangAll(char *p, char *key); //替换所有的 p
int _size(); //返回字符串size
private:
int size; //字符串的长度
char *pstr; //字符串源
};
/**************************************************************************************************/
/*************************************************************************************************/
/************************************mystring.cpp*************************************************/
#include "mystring.h"
ostream& operator <<(ostream &, const mystring & myTT) //友元重载输出
{
<span style="white-space:pre"> </span>return cout << myTT.pstr;
}
istream & operator >>(istream & is, mystring & MyTT) //友元重载输入
{
<span style="white-space:pre"> </span>is>>MyTT.pstr; //pstr
<span style="white-space:pre"> </span>MyTT.size = strlen(MyTT.pstr);
<span style="white-space:pre"> </span>char *tmp = new char[MyTT.size + 1];
<span style="white-space:pre"> </span>strcpy(tmp, MyTT.pstr); //需重新拷贝进来,原MyTT.pstr并没有分配内存
<span style="white-space:pre"> </span>MyTT.pstr = tmp;
<span style="white-space:pre"> </span>return is;
}
mystring::mystring() //构造 0
{
<span style="white-space:pre"> </span>this->size = 1;
<span style="white-space:pre"> </span>this->pstr = new char[1];
<span style="white-space:pre"> </span>*(this->pstr) = '\0';
}
mystring::mystring(char *p) //构造1
{
<span style="white-space:pre"> </span>this->size = strlen(p);
<span style="white-space:pre"> </span>this->pstr = new char[this->size + 1];
<span style="white-space:pre"> </span>memset(this->pstr, 0, this->size + 1);
<span style="white-space:pre"> </span>strcpy(this->pstr, p);
}
mystring::mystring(const mystring & str2) //构造2
{
<span style="white-space:pre"> </span>this->size = str2.size;
<span style="white-space:pre"> </span>char *tmp = new char[this->size + 1];
<span style="white-space:pre"> </span>memset(tmp, 0, this->size + 1);
<span style="white-space:pre"> </span>strcpy(tmp, str2.pstr);
<span style="white-space:pre"> </span>free(this->pstr);
<span style="white-space:pre"> </span>this->pstr = tmp;
}
mystring::~mystring() //析构
{
<span style="white-space:pre"> </span>free(this->pstr);
<span style="white-space:pre"> </span>this->pstr = nullptr;
}
int mystring::_size()
{
<span style="white-space:pre"> </span>return this->size;
}
char * mystring::srea(char *p) //查找字符串 ,返回字符串所在位置首指针
{
<span style="white-space:pre"> </span>int plen = strlen(p);
<span style="white-space:pre"> </span>int i = 0;
<span style="white-space:pre"> </span>while (i < this->size)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>if (this->pstr[i] == *p)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>int j = 0;
<span style="white-space:pre"> </span>int flag = 1;
<span style="white-space:pre"> </span>for (; j < plen; j++)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>if (this->pstr[i + j] != p[j])
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>flag = 0;
<span style="white-space:pre"> </span>break;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if (flag)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>return this->pstr + i;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>i++;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return nullptr;
}
void mystring::Insert(char *p, char *key)//key 要插入的字符串 p插入的位置字符串后面
{
<span style="white-space:pre"> </span>char *tmp = this->srea(p);
<span style="white-space:pre"> </span>if (tmp != nullptr)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>char * buf = new char[this->size + strlen(key) + 1];
<span style="white-space:pre"> </span>memset(buf, 0, this->size + strlen(key) + 1); //重新分配内存并初始化
<span style="white-space:pre"> </span>char cc = *(tmp + strlen(p));
<span style="white-space:pre"> </span>*(tmp + strlen(p)) = '\0'; //方便拷贝第一段
<span style="white-space:pre"> </span>strcpy(buf, this->pstr);
<span style="white-space:pre"> </span>strcpy(buf + (tmp - this->pstr) + strlen(p), key); //插入
<span style="white-space:pre"> </span>*(tmp + strlen(p) + 1) = cc;
<span style="white-space:pre"> </span>strcpy(buf + (tmp - this->pstr) + strlen(p) + strlen(key), tmp + strlen(p) + 1); //拷贝后面的内容
<span style="white-space:pre"> </span>free(this->pstr);
<span style="white-space:pre"> </span>this->pstr = buf;
<span style="white-space:pre"> </span>this->size = this->size + strlen(key);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>else
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>cout << "Can't find this string" << endl;
<span style="white-space:pre"> </span>}
}
void mystring::Append(char *key) //尾部插入
{
<span style="white-space:pre"> </span>char *tmp = new char[this->size + strlen(key) + 1];
<span style="white-space:pre"> </span>memset(tmp, 0, this->size + strlen(key) + 1);
<span style="white-space:pre"> </span>strcpy(tmp, this->pstr);
<span style="white-space:pre"> </span>strcpy(tmp + this->size, key);
<span style="white-space:pre"> </span>free(this->pstr);
<span style="white-space:pre"> </span>this->pstr = tmp;
<span style="white-space:pre"> </span>this->size = this->size + strlen(key);
}
void mystring::StartInsert(char *key) //头部插入
{
<span style="white-space:pre"> </span>char *tmp = new char[this->size + strlen(key) + 1];
<span style="white-space:pre"> </span>memset(tmp, 0, this->size + strlen(key) + 1);
<span style="white-space:pre"> </span>strcpy(tmp, key);
<span style="white-space:pre"> </span>strcpy(tmp + strlen(key), this->pstr);
<span style="white-space:pre"> </span>free(this->pstr);
<span style="white-space:pre"> </span>this->pstr = tmp;
<span style="white-space:pre"> </span>this->size = this->size + strlen(key);
}
void mystring::del(char *p) //删除首个出现的p字符串
{
<span style="white-space:pre"> </span>char *tmp = this->srea(p);
<span style="white-space:pre"> </span>if (tmp != nullptr)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>char *ptmp = new char[this->size - strlen(p) + 1];
<span style="white-space:pre"> </span>memset(ptmp, 0, this->size - strlen(p) + 1); //重新开辟内存
<span style="white-space:pre"> </span>*tmp = '\0';
<span style="white-space:pre"> </span>strcpy(ptmp, this->pstr); //拷贝
<span style="white-space:pre"> </span>strcpy(ptmp + (tmp - this->pstr), tmp + strlen(p)); //拷贝字符串后面的部分
<span style="white-space:pre"> </span>free(this->pstr); //释放原字符串池
<span style="white-space:pre"> </span>this->pstr = ptmp;
<span style="white-space:pre"> </span>this->size -= strlen(p); //刷新对象属性
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>else
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>cout << "Can't find this string" << endl;
<span style="white-space:pre"> </span>}
}
void mystring::exchang(char *p, char *key) //替换首个出现的 p字符串
{
<span style="white-space:pre"> </span>char *tmp = this->srea(p);
<span style="white-space:pre"> </span>if (tmp != nullptr)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>char *ptmp = new char[this->size + strlen(key) + 1];
<span style="white-space:pre"> </span>memset(ptmp, 0, this->size + strlen(key) + 1);
<span style="white-space:pre"> </span>*tmp = '\0';
<span style="white-space:pre"> </span>strcpy(ptmp, this->pstr); //拷贝前面
<span style="white-space:pre"> </span>strcpy(ptmp + (tmp - this->pstr), key); //拷贝用于替换的key
<span style="white-space:pre"> </span>strcpy(ptmp + (tmp - this->pstr) + strlen(key), tmp + strlen(p)); //拷贝后面的字符串
<span style="white-space:pre"> </span>free(this->pstr);
<span style="white-space:pre"> </span>this->pstr = ptmp;
<span style="white-space:pre"> </span>this->size = this->size - strlen(p) + strlen(key); //释放并刷新
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>else
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>cout << "Can't find this string" << endl;
<span style="white-space:pre"> </span>}
}
void mystring::delAll(char *pkey)
{
<span style="white-space:pre"> </span>char *p = srea(pkey);
<span style="white-space:pre"> </span>if (p != nullptr)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>del(pkey);
<span style="white-space:pre"> </span>delAll(pkey); //递归调用
<span style="white-space:pre"> </span>}
}
void mystring::exchangAll(char *p, char *key)
{
<span style="white-space:pre"> </span>char *ptmp = srea(p);
<span style="white-space:pre"> </span>if (ptmp != nullptr)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>exchang(p, key);
<span style="white-space:pre"> </span>exchangAll(p, key); //递归调用
<span style="white-space:pre"> </span>}
}
char & mystring::operator[](int n) //重载[]
{
<span style="white-space:pre"> </span>return this->pstr[n];
}
int mystring::mystrcmp(const mystring *str1, const mystring *str2) //比较函数
{
<span style="white-space:pre"> </span>if (str1->size > str2->size)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>return 1;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>else if (str1->size < str2->size)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>return -1;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>else
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>int flag = 0;
<span style="white-space:pre"> </span>int i = 0;
<span style="white-space:pre"> </span>while (i++ < str1->size)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>if (str1->pstr[i] != str2->pstr[i])
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>if (str1->pstr[i] > str2->pstr[i])
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>return 1;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>else
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>return -1;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return 0;
<span style="white-space:pre"> </span>}
}
mystring & mystring::operator+=(char *p)
{
<span style="white-space:pre"> </span>char *ptmp = new char[this->size + strlen(p) + 1];
<span style="white-space:pre"> </span>strcpy(ptmp, this->pstr);
<span style="white-space:pre"> </span>strcpy(ptmp + this->size, p);
<span style="white-space:pre"> </span>free(this->pstr); //释放原指针
<span style="white-space:pre"> </span>this->pstr = ptmp; //重新定义指向
<span style="white-space:pre"> </span>this->size += this->size + strlen(p); //修改原字符串的长度值
<span style="white-space:pre"> </span>return *this;
}
mystring & mystring::operator+=(const mystring& mystr) //重载 +=
{
<span style="white-space:pre"> </span>char *ptmp = new char[this->size + mystr.size + 1];
<span style="white-space:pre"> </span>strcpy(ptmp, this->pstr);
<span style="white-space:pre"> </span>strcpy(ptmp + this->size, mystr.pstr);
<span style="white-space:pre"> </span>free(this->pstr); //释放原指针
<span style="white-space:pre"> </span>this->pstr = ptmp; //重新定义指向
<span style="white-space:pre"> </span>this->size += this->size + mystr.size; //修改原字符串的长度值
<span style="white-space:pre"> </span>return *this;
}
mystring & mystring::operator=(const mystring & mystr)
{
<span style="white-space:pre"> </span>if (this->size >= strlen(mystr.pstr)) //不用重新分配内存
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>memcpy(this->pstr, 0, this->size + 1);
<span style="white-space:pre"> </span>strcpy(this->pstr, mystr.pstr);
<span style="white-space:pre"> </span>this->size = mystr.size;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>else //重新分配
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>char *tmp = new char[strlen(mystr.pstr) + 1];
<span style="white-space:pre"> </span>free(this->pstr);
<span style="white-space:pre"> </span>this->pstr = nullptr;
<span style="white-space:pre"> </span>strcpy(tmp, mystr.pstr);
<span style="white-space:pre"> </span>this->pstr = tmp;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return *this;
}
mystring & mystring::operator=(char *p)
{
<span style="white-space:pre"> </span>if (this->size >= strlen(p)) //同上
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>memcpy(this->pstr, 0, this->size + 1);
<span style="white-space:pre"> </span>strcpy(this->pstr, p);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>else
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>char *tmp = new char[strlen(p) + 1];
<span style="white-space:pre"> </span>free(this->pstr);
<span style="white-space:pre"> </span>this->pstr = nullptr;
<span style="white-space:pre"> </span>strcpy(tmp, p);
<span style="white-space:pre"> </span>this->pstr = tmp;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return *this;
}