您的位置:首页 > 编程语言 > C语言/C++

C++自定义String类(简单的实现功能)

2017-07-12 16:33 381 查看
#pragma once

#include "targetver.h"

#include<cassert>

#include <stdio.h>

#include <tchar.h>

#include<iostream>
using namespace std;

#pragma once

class MyString

{

public:
MyString(char *s);
MyString();
MyString(MyString & a);
char* mystrcopy(char *str1, const char * str2);//自定义strcpy函数
MyString &mystrcopy(MyString& a, const MyString &b);//自定义strcpy函数形参为两个对象
MyString &mystrcopy( const char * str2);//字符指针copy到自身
MyString &mystrcopy(const MyString &a);//另一个对象copy到自身
unsigned int mystrlen(const char * str);//自定义strlen函数
unsigned int mystrlen()const;//直接计算自身长度
unsigned int mystrlen(const MyString &a);//计算另一个对象的长度
char * mystrcat(char* str1, const char* str2);//自定义strcat函数
MyString &mystrcat(MyString &a, const MyString &b);//链接两个对象
MyString &mystrcat(const char* str2);//将另一字符串链接自身
MyString & mystrcat(const MyString &a);//将另一个对象链接至自身
int Mystrcmp(const char * str1,const char * str2);//自定义比较函数
int Mystrcmp(const MyString& a, const MyString& b);//比较两个对象
int Mystrcmp( const char * str2);//比较自身和一个字符串
int Mystrcmp(const MyString &a);//比较自身和一个对象
void GetNext(int Next[], const char * str);//跳转数组
int FindStr(const char *str1,const char *str2);//查询参数字符串在自身的位置,返回位置
void GetNext(int Next[], const MyString &b);//跳转数组参数为对象的引用
int FindStr(const MyString &a,const MyString &b);//查询参数字符串在自身的位置,返回位置
int FindStr(const MyString &b);//查询参数字符串在自身的位置,返回位置
int myatoi(char *str);//字符串转int
int myatoi(const MyString &a);//字符串转int
int myatoi();//字符串转int
char *my_itoa( int num, char *str, int radix);//int转字符串
MyString &my_itoa(int num, MyString & a, int radix);//int转字符串
MyString &my_itoa(int num,  int radix);//int转字符串
char* antitone(char *str);//反序
MyString antitone(MyString &a);//反序
MyString & antitone();//反序
char* insert(int n, char *str, char *c);//插入
MyString & insert(int n, MyString& a, char *c);//插入对象为参数
MyString & insert(int n,  char *c);//插入自身为参数
MyString & insert(int n, MyString& a, const MyString& b);//插入对象插对象
MyString & insert(int n, const MyString& b);//插入
char *ReMove(unsigned int m, char*str, unsigned int n);//删除
MyString &ReMove(unsigned int m, MyString&a, unsigned int n);//从对象中删除
MyString &ReMove(unsigned int m, unsigned int n);//从自身删除
char* &GETS(){ return s; }
friend ostream &operator<<(ostream &a, MyString & b);//重载输出流
friend istream &operator>>(istream &a, MyString & b);//重载输入流
friend MyString&operator+=(MyString &a, const MyString & b);//重载+=实现字符串链接
friend MyString operator+(MyString &a, const MyString & b);//重载+实现字符串链接但不改变对象
friend MyString&operator-=(MyString &a, const MyString & b);//重载-=实现字符串删除                               当a中没有b是不变
friend MyString operator-(MyString &a, const MyString & b);//重载-实现字符串删除但不改变对象                     当a中没有b是不变
MyString&operator=( const MyString & b);//由于用到堆区赋值运算符需要重写
static char* pp;
static char* hh;
static int aa;
static bool rr;
virtual ~MyString();

protected:

private:
char * s;

};

#include "stdafx.h"

#include "MyString.h"

char *MyString::hh = NULL;

char* MyString::pp = NULL;

int MyString::aa = 0;

bool MyString::rr = true;

char *MyString::mystrcopy(char *str1, const char *  str2)//自定义strcpy函数

{
hh = str1;
assert(hh != NULL&&str2 != NULL);
while ((*hh++ = *str2++) != '\0'){}
hh = NULL;
return str1;

}

MyString &MyString::mystrcopy(MyString& a, const MyString& b)//自定义strcpy函数形参为两个对象

{
hh = a.s;
pp= b.s;
assert(hh != NULL&&pp != NULL);
while ((*hh++ = *pp++) != '\0'){}
hh = NULL;
pp = NULL;
return a;

}

MyString & MyString::mystrcopy(const MyString &a)//自定义strcpy函数形参为一个对象

{
pp = this->s;
hh = a.s;
assert(pp != NULL&&hh != NULL);
while ((*pp++ = *hh++) != '\0'){}
hh = NULL;
pp = NULL;
return *this;

}

MyString & MyString::mystrcopy(const char * str2)//自定义strcpy函数形参为一个字符串

{
pp = this->s;
assert(pp != NULL&&str2 != NULL);
while ((*pp++ = *str2++) != '\0'){}
pp = NULL;
return *this;

}

unsigned int MyString::mystrlen(const char * str)//自定义strlen函数

{
assert(str != NULL);
aa = 0;
for (; *str++ != '\0'; aa++){}
return aa;

}

unsigned int MyString::mystrlen()const//自定义strlen函数另一无形参为自身

{
pp = s;
assert(pp != NULL);
aa = 0;
for (; *pp++ != '\0'; aa++){}
pp = NULL;
return aa;

}

unsigned int MyString::mystrlen(const MyString &a)//自定义strlen函数另一参数为形参为一个对象

{
pp = a.s;
assert(pp != NULL);
aa= 0;
for (; *pp++ != '\0'; aa++){}
pp = NULL;
return aa;

}

char * MyString::mystrcat(char* str1, const char* str2)//自定义strcat函数

{
pp= str1;
assert(pp != NULL&&str2 != NULL);
for (; *pp++ != '\0';){}
for (pp--; (*pp++ = *str2++) != '\0';){}
pp = NULL;
return str1;

}

MyString &MyString::mystrcat(MyString& a, const MyString& b)//自定义strcat函数形参为两个对象

{
pp = new char[ a.mystrlen() +b.mystrlen()+ 1];
mystrcopy(pp, a.s);
delete[]a.s;
a.s =pp;
hh = b.s;
assert(pp != NULL&&hh != NULL);
for (; *pp++ != '\0';){}
for (pp--; (*pp++ = *hh++) != '\0';){}
pp = NULL;
hh = NULL;
return a;

}

MyString & MyString::mystrcat(const char* str2)//自定义strcat函数形参为一个字符串

{
pp = this->s;
assert(pp != NULL&&str2 != NULL);
for (; *pp++ != '\0';){}
for (pp--; (*pp++ = *str2++) != '\0';){}
pp = NULL;
return *this;

}

MyString & MyString::mystrcat(const MyString &a)//自定义strcat函数形参为一个对象

{
pp= new char[mystrlen() + a.mystrlen() + 1];
mystrcopy(pp,this-> s);
delete[]this->s;
this->s = pp;

    hh= a.s;
assert(pp != NULL&&hh != NULL);
for (; *pp++ != '\0';){}
for (pp--; (*pp++ = *hh++) != '\0';){}
pp = NULL;
hh = NULL;
return *this;

}

int MyString::Mystrcmp(const MyString &a, const MyString& b)//自定义比较函数形参为两个对象

{
pp = a.s;
hh = b.s;
assert(pp != NULL&&hh != NULL);
while ((*pp++ == *hh++) && (*pp == '\0') && (*hh == '\0'))
{
pp = NULL;
hh = NULL;
return 0;
}
return *--pp > *--hh? 1 : -1;

}

int MyString::Mystrcmp(const char * str1, const char * str2)//自定义比较函数

{
assert(str1 != NULL&&str2 != NULL);
while ((*str1++ == *str2++) && (*str1 == '\0') && (*str2 == '\0'))
{
return 0;
}
return *--str1 > *--str2 ? 1 : -1;

}

int MyString::Mystrcmp( const char * str2)//自定义比较函数形参为一个字符串

{
pp = s;
assert(pp != NULL&&str2 != NULL);
while ((*pp++ == *str2++) && (*pp == '\0') && (*str2 == '\0'))
{
pp = NULL;
return 0;
}
return *--pp > *--str2? 1 : -1;

}

int MyString::Mystrcmp(const MyString &a)//自定义比较函数形参为一个对象

{
pp = s;

    hh= a.s;
assert(pp != NULL&&hh != NULL);
while ((*pp++ == *hh++) && (*pp == '\0') && (*hh == '\0'))
{
pp = NULL;
hh = NULL;
return 0;
}
return *--pp > *--hh ? 1 : -1;

}

void MyString::GetNext(int Next[], const char * str)//求跳转数组

{
unsigned int i = 0;
int j = -1;
Next[0] = -1;
while (i < mystrlen(str))
{
if (j == -1 || str[i] == str[j])
{
i++;
j++;
Next[i] = j;
}
else
{
j = Next[j];
}
}

}

int MyString::FindStr(const char *str1,const char * str2)//查找字符串

{
int *Next = new int[mystrlen(str2)];
GetNext(Next, str2);
unsigned int i = 0;
int j = 0;
while (i < mystrlen(str1) || i <mystrlen(str2))
{
if (j==-1||str1[i] == str2[j])
{
i++;
j++;
}
else
j = Next[j];
if (j == mystrlen(str2))
return i - j;
}
return -1;
delete[]Next;

}

void MyString::GetNext(int Next[],const MyString &b)//跳转数组参数为对象的引用

{
unsigned int i = 0;
int j = -1;
Next[0] = -1;
while (i < mystrlen(b.s))
{
if (j == -1 || b.s[i] == b.s[j])
{
i++;
j++;
Next[i] = j;
}
else
{
j = Next[j];
}
}

}

int MyString::FindStr(const MyString &a,const MyString &b)//查询参数字符串在自身的位置,返回位置

{
int *Next = new int[mystrlen(b.s)];
GetNext(Next, b.s);
unsigned int i = 0;
int j = 0;
while (i < mystrlen(a.s) || i <mystrlen(b.s))
{
if (j == -1 || a.s[i] == b.s[j])
{
i++;
j++;
}
else
j = Next[j];
if (j == mystrlen(b.s))
return i - j;
}
return -1;
delete[]Next;

}

int MyString::FindStr(const MyString &b)//查询参数字符串在自身的位置,返回位置

{
int *Next = new int[mystrlen(b.s)];
GetNext(Next, b.s);
unsigned int i = 0;
int j = 0;
while (i < mystrlen(this->s) || i <mystrlen(b.s))
{
if (j == -1 || this->s[i] == b.s[j])
{
i++;
j++;
}
else
j = Next[j];
if (j == mystrlen(b.s))
return i - j;
}
return -1;
delete[]Next;

}

int MyString:: myatoi(char *str)//字符串转int

{
while (*str == ' '){ str++; }//前面为空格跳过
rr = (*str == '-' || *str == '+') && (*str++ == '-') ? false : true;//若为正负号跳过并决定改变标签的值
int sum = 0;
for (; *str >= '0'&&*str <= '9' && (sum = sum * 10 + *str++ - '0')?1:1;);//符号转数字
return !rr ? -sum : sum;

}

int MyString::myatoi(const MyString& a)//字符串转int

{
pp = a.s;
while (*pp== ' '){ pp++; }//前面为空格跳过
rr = (*pp== '-' || *pp== '+') && (*pp++ == '-') ? false : true;//若为正负号跳过并决定改变标签的值
int sum = 0;
for (; *pp >= '0'&&*pp <= '9'&&(sum = sum * 10 + *pp++ - '0'););//符号转数字
pp = NULL;
return !rr ? -sum : sum;

}

int MyString::myatoi()//字符串转int

{
pp= this->s;
while (*pp == ' '){ pp++; }//前面为空格跳过
rr = (*pp == '-' || *pp == '+') && (*pp++ == '-') ? false : true;//若为正负号跳过并决定改变标签的值
aa= 0;
for (; *pp >= '0'&&*pp <= '9' && (aa = aa * 10 + *pp++ - '0'););//符号转数字
pp = NULL;
return !rr ? -aa : aa;

}

char* MyString:: antitone(char *str)//反序

{
for (unsigned int i = 0; i < mystrlen(str)/2; ++i)
{
char aa = str[i];
str[i] = str[mystrlen(str) - 1 - i];
str[mystrlen(str) - 1 - i] = aa;
}
return str;

}

MyString MyString::antitone(MyString& a)//反序

{
for (unsigned int i = 0; i < mystrlen(a.s) / 2; ++i)
{
char aa = a.s[i];
a.s[i] = a.s[mystrlen(a.s) - 1 - i];
a.s[mystrlen(a.s) - 1 - i] = aa;
}
return a;

}

MyString& MyString::antitone()//反序

{
for (unsigned int i = 0; i < mystrlen(this->s) / 2; ++i)
{
char aa = this->s[i];
this->s[i] = this->s[mystrlen(this->s) - 1 - i];
this->s[mystrlen(this->s) - 1 - i] = aa;
}
return *this;

}

char* MyString::insert(int n, char * str, char* c)//插入

{
hh = str;
for (int i = 0; i < n&& hh++; ++i);//指针后移至n处
pp = hh;
char *oo = c;
for (unsigned int i = 0; i <= mystrlen(hh); ++i)
{
hh[mystrlen(
eb47
hh) + mystrlen(c) - i] = hh[mystrlen(hh) - i];
}//后移
for (unsigned int i = 0; i < mystrlen(c) && (*pp++ = *oo++); ++i);//插入
return str;



MyString &MyString::insert(int n, MyString& a, char* c)//插入

{
char*ss = new char[mystrlen(a) + mystrlen(c) + 1];
mystrcopy(ss, a.s);
delete[]a.s;
hh=a.s = ss;
for (int i = 0; i < n&& hh++; ++i);//指针后移至n处
pp = hh;
char *oo = c;
for (unsigned int i = 0; i <= mystrlen(hh); ++i)//后移
{
hh[mystrlen(hh) + mystrlen(c) - i] = hh[mystrlen(hh) - i];
}
for (unsigned int i = 0; i < mystrlen(c) && (*pp++ = *oo++); ++i);//插入
return a;

}

MyString &MyString::insert(int n, char* c)//插入

{
char*ss = new char[mystrlen(this->s) + mystrlen(c) + 1];
mystrcopy(ss, this->s);
delete[]this->s;
hh = this->s=ss;
for (int i = 0; i < n&& hh++; ++i);//指针后移至n处
pp = hh;
char *oo = c;
for (unsigned int i = 0; i <= mystrlen(hh); ++i)//后移
{
hh[mystrlen(hh) + mystrlen(c) - i] = hh[mystrlen(hh)  - i];
}
for (unsigned int i = 0; i < mystrlen(c) && (*pp++ = *oo++); ++i);//插入
return *this;

}

MyString & MyString::insert(int n, MyString& a, const MyString& b)//插入

{
char*ss = new char[mystrlen(a) + mystrlen(b.s) + 1];
mystrcopy(ss, a.s);
delete[]a.s;
hh = a.s = ss;
for (int i = 0; i < n&& hh++; ++i);//指针后移至n处
pp = hh;
char *oo = b.s;
for (unsigned int i = 0; i <= mystrlen(hh); ++i)//后移
{
hh[mystrlen(hh) + mystrlen(b.s) - i] = hh[mystrlen(hh) - i];
}
for (unsigned int i = 0; i < mystrlen(b.s); ++i)//插入
{
*pp++ = *oo++;
}
return a;

}

MyString & MyString::insert(int n, const MyString& b)//插入

{
char*ss = new char[mystrlen(this->s) + mystrlen(b.s) + 1];
mystrcopy(ss, this->s);
delete[]this->s;
hh = this->s = ss;
for (int i = 0; i < n&& hh++; ++i);//指针后移至n处
pp = hh;
char *oo = b.s;
for (unsigned int i = 0; i <= mystrlen(hh); ++i)//后移
{
hh[mystrlen(hh) + mystrlen(b.s) - i] = hh[mystrlen(hh) - i];
}
for (unsigned int i = 0; i < mystrlen(b.s); ++i)//插入
{
*pp++ = *oo++;
}
return *this;

}

char *MyString::my_itoa(int num, char *str, int radix)//自定义itoa函数

{
rr= num>0 ?true:false;
pp = hh=str;
if (radix == 2)//负数二进制输出
{
for (int i = 0; i<32 && (*hh++ = num < 0 ? 1 + '0' : '0'); i++){num <<= 1;}
*hh = '\0';
}
else
{
num = num>0 ? num : -num;
if (!rr && (*pp++ = '-')){ hh = pp; }
for (; num && (*pp++ = radix != 16 ? num%radix + '0' : (num%radix) >= 10 ? 'A' + num%radix - 10 : num%radix + '0'); num /= radix);
*pp = '\0';
antitone(hh);//反序
}
pp = NULL;
hh = NULL;
return str;

}

MyString &MyString::my_itoa(int num, MyString & a, int radix)//int转字符串

{
rr = num>0 ? true : false;
if (a.s != NULL)
delete[]a.s;
a.s = new char[64];
pp = hh = a.s;
if (radix == 2)//负数二进制输出
{
for (int i = 0; i<32 && (*hh++ = num < 0 ? 1 + '0' : '0'); i++){ num <<= 1; }
*hh = '\0';
}
else
{
num = num>0 ? num : -num;
if (!rr && (*pp++ = '-')){ hh = pp; }
for (; num && (*pp++ = radix != 16 ? num%radix + '0' : (num%radix) >= 10 ? 'A' + num%radix - 10 : num%radix + '0'); num /= radix);
*pp = '\0';
antitone(hh);//反序
}
pp = NULL;
hh = NULL;
pp = new char[a.mystrlen() + 1];
mystrcopy(pp, a.s);
delete[]a.s;
a.s = pp;
pp = NULL;
return a;

}

MyString &MyString::my_itoa(int num, int radix)//int转字符串

{
rr = num>0 ? true : false;
if (this->s != NULL)
delete[]this->s;
this->s= new char[64];
pp = hh = this->s;
if (radix == 2)//负数二进制输出
{
for (int i = 0; i<32 && (*hh++ = num < 0 ? 1 + '0' : '0'); i++){ num <<= 1; }
*hh = '\0';
}
else
{
num = num>0 ? num : -num;
if (!rr && (*pp++ = '-')){ hh = pp; }
for (; num && (*pp++ = radix != 16 ? num%radix + '0' : (num%radix) >= 10 ? 'A' + num%radix - 10 : num%radix + '0'); num /= radix);
*pp = '\0';
antitone(hh);//反序
}
pp = NULL;
hh = NULL;
pp = new char[this->mystrlen() + 1];
mystrcopy(pp, this->s);
delete[] this->s;
this->s = pp;
pp = NULL;
return *this;

}

char *MyString::ReMove(unsigned int m, char*str, unsigned int n)//删除从m位置到n位置字符

{
assert(m <= mystrlen(str) && n <= mystrlen(str) && n >= m &&m>= 0);
hh=pp = str;
for (unsigned int i = 0; i < m&&(pp++ ? 1 : 1); ++i);
for (unsigned int i = 0; i < n && (hh++ ? 1 : 1); ++i);
for (unsigned int i = 0; i <= mystrlen(hh); ++i)
{
pp[i] = pp[i + (n - m)];
}
return str;

}

MyString &MyString::ReMove(unsigned int m, MyString& a, unsigned int n)//删除

{
assert(m <= mystrlen(a.s) && n <= mystrlen(a.s) && n >= m &&m >= 0);
hh = pp = a.s;
for (unsigned int i = 0; i < m && (pp++ ? 1 : 1); ++i);
for (unsigned int i = 0; i < n && (hh++ ? 1 : 1); ++i);
for (unsigned int i = 0; i <= mystrlen(hh); ++i)
{
pp[i] = pp[i + (n - m)];
}
return a;

}

MyString &MyString::ReMove(unsigned int m, unsigned int n)//删除

{
assert(m <= mystrlen(this->s) && n <= mystrlen(this->s) && n >= m &&m >= 0);
hh = pp = this->s;
for (unsigned int i = 0; i < m && (pp++ ? 1 : 1); ++i);
for (unsigned int i = 0; i < n && (hh++ ? 1 : 1); ++i);
for (unsigned int i = 0; i <= mystrlen(hh); ++i)
{
pp[i] = pp[i + (n - m)];
}
return *this;

}

ostream &operator<<(ostream &a, MyString & b)//重载输出流

{
return a << b.s;

}

istream &operator>>(istream &a, MyString & b)//重载输入流

{
return  a >> b.s;

}

MyString&operator+=(MyString &a, const MyString & b)//重载'+='实现字符串连接

{
assert(a.s != NULL&&b.s != NULL);
char *ss = new char[a.mystrlen() + b.mystrlen() + 1];
a.mystrcopy(ss, a.s);
delete[]a.s;
a.s = ss;
int j = 0;
for (; *ss++ != '\0';){}
for (--ss; (*ss++ = *(b.s+j)) != '\0';++j){}
return a;

}

MyString operator+(MyString &a, const MyString & b)//重载+实现字符串链接但不改变对象

{
MyString c = a;
assert(c.s != NULL&&b.s != NULL);
char *ss = new char[c.mystrlen() + b.mystrlen() + 1];
c.mystrcopy(ss, c.s);
delete[]c.s;
c.s = ss;
int j = 0;
for (; *ss++ != '\0';){}
for (--ss; (*ss++ = *(b.s + j)) != '\0'; ++j){}
return c;

}

MyString& MyString::operator=(const MyString & b)//由于用到堆区赋值运算符需要重写

{
this->s = new char[b.mystrlen() + 1];
mystrcopy(this->s, b.s);
return *this;

}

MyString&operator-=(MyString &a, const MyString & b)//重载-=实现字符串删除

{
if (a.FindStr(b) != -1)
{
char*pp = a.s, *hh = a.s;
for ( int i = 0; i < a.FindStr(b) && (pp++ ? 1 : 1); ++i);
for (unsigned int i = 0; i < a.FindStr(b) + b.mystrlen() && (hh++ ? 1 : 1); ++i);
for (unsigned int i = 0; i <= a.mystrlen(hh); ++i)
{
pp[i] = pp[i + (b.mystrlen())];
}
return a;
}
else
return a;

}

MyString operator-(MyString &a, const MyString & b)//重载-实现字符串删除但不改变对象

{
MyString c = a;
if (c.FindStr(b) != -1)
{
char*pp = c.s, *hh = c.s;
for (int i = 0; i < c.FindStr(b) && (pp++ ? 1 : 1); ++i);
for (unsigned int i = 0; i < c.FindStr(b) + b.mystrlen() && (hh++ ? 1 : 1); ++i);
for (unsigned int i = 0; i <= c.mystrlen(hh); ++i)
{
pp[i] = pp[i + (b.mystrlen())];
}
return c;
}
else
return c;

}

MyString::MyString(){ this->s = NULL; }

MyString::MyString(char * s)

{
if (s != NULL)
{
this->s = new char[mystrlen(s) + 1];
mystrcopy(this->s, s);
}
else
return;

}

MyString::MyString(MyString & a)

{
this->s = new char[mystrlen(a.s) + 1];
mystrcopy(this->s, a.s); 

}

MyString::~MyString()//析构函数

{
delete[]s;//释放堆内存

}

// string.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include "MyString.h"

int _tmain(int argc, _TCHAR* argv[])

{
char as[90] = "abcdef";
char as1[90] = "bcd";
MyString c=as;
MyString d = as1;
MyString f = as1;
//c.insert(0, as1, as);
//cout << c.Mystrcmp(d) << endl;
//cout << d.myatoi(as1) << endl;
//cout << d.my_itoa(-56, as, 2) << endl;
//cout << d.insert(0,as)<< endl;
cout <<c-d<< endl;
cout << c << endl;
//cout << c << endl;
//cout << d << endl;
system("pause");
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  控制台 c++ String类