💖作者:小树苗渴望变成参天大树🎈
🎉作者宣言:认真写好每一篇博客💤
🎊作者gitee:gitee✨
💞作者专栏:C语言,数据结构初阶,Linux,C++ 动态规划算法\🎄
如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧!
文章目录
- 前言
前言
大家好,今天带来的是string类的模拟实现,由于类的实现内容非常多,不好一个一个给大家介绍,所以我直接放源码,大家自己学习,不理解的评论区留言
模拟实现:
string.h
#pragma once
#include<string.h>
#include<iostream>
#include<assert.h>
using namespace std;
namespace xdh//先弄一个命名空间域,防止和库里面的冲突
{
class string
{
public:
//==========构造函数=============
//写一个经典的构造函数
/*string(const char* str)
:_str(new char[strlen(str)])
,_size(strlen(str))
,_capacity(strlen(str))
{
strcpy(_str, str);
}*/
//无参构造器
/* string()
:_str(new char[1])
, _size(0)
,_capacity(0)
{
_str[0] ='\0';
}*/
//合并构造器
string(const char* str = "")
{
_size = strlen(str);
_capacity = strlen(str);
_str = new char[strlen(str)+1];
//strcpy(_str,str);//这个可以不用替换成memcpy因为传进来本来就是字符串,以\0结尾的
memcpy(_str, str, _size + 1);//strcpy默认拷贝到\0结束,而memcpy需要手动进行拷贝
}
//==========swap函数的实现==========
void swap(string& s)
{
std::swap(_str,s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
}
//=============拷贝构造函数==========
string(const string& s)
{
int len = strlen(s.c_str());
_str = new char[len + 1];
_size = len + 1;
_capacity = _size;
for (int i = 0; i <len; i++)
{
_str[i] = s[i];
}
_str[len] = '\0';
}
//字符串的大小
size_t size() const
{
return _size;
}
//字符串的容量
size_t capacity() const
{
return _capacity;
}
//转成指针
const char* c_str() const
{
return _str;
}
//operator[]的重载
char& operator[] (size_t pos)//具有读写功能
{
assert(pos < _size);
return _str[pos];
}
const char& operator[] (size_t pos) const//只具有读功能
{
assert(pos < _size);
return _str[pos];
}
//=================迭代器的实现(类似于指针)===============
typedef char* iterator;
typedef const char* const_iterator;
typedef char* reverse_iterator;
typedef const char* const_reverse_iterator;
iterator begin()
{
return _str;
}
iterator end()
{
return _str+_size;
}
const_iterator cbegin()const
{
return _str;
}
const_iterator cend()const
{
return _str + _size;
}
reverse_iterator rbegin()
{
return _str + _size;
}
reverse_iterator rend()
{
return _str;
}
const_reverse_iterator crbegin() const
{
return _str + _size;
}
const_reverse_iterator crend() const
{
return _str;
}
//reverve扩容函数的实现
void reserve(size_t n = 0)
{
char* tmp = new char[n+1];
//strcpy(tmp, _str);使用这个拷贝到中间字符就廷下来了,后面的拷贝不到了
memcpy(tmp, _str, _size+1);
delete[] _str;
_str = tmp;
_capacity = n;
}
//=========resize函数的实现
void resize(size_t n, char c='\0')
{
if (n < _size)
{
_str[n] = '\0';
_size = n;
}
else
{
reserve(n);
for (int i = _size; i < n; i++)
{
_str[i] = c;
}
_str[n-1] = '\0';
_size = n;
}
}
//==========push_back的实现=========(实现经典的常用的)
void push_back(char c)
{
if (_size == _capacity)
{
reserve(_capacity==0?4:_capacity*2);
}
_str[_size] = c;
++_size;
_str[_size] = '\0';
}
//==========append的实现=-==========(实现经典的常用的)
void append(const char* s)
{
int len = strlen(s);
if (_size + len > _capacity)
{
reserve(_size + len);
}
/* for (int i = 0; i <=len; i++)
{
_str[_size +i] = s[i];
}*/
//strcpy(_str+ len, s);这个也可以不用换,传进来的字符串,为了保持一致性,也替换一下
memcpy(_str + _size, s, len+1);
_size += len+1;
}
//==========opeartor+=函数=========(复用前面的push_back和append)
string& operator+= (const char* s)
{
append(s);
return *this;
}
string& operator+= (char c)
{
push_back(c);
return *this;
}
//==========insert函数的实现=============
string& insert(size_t pos, const char* s) //(从pos的位置插入一个字符串)
{
assert(pos <= _size);
int len = strlen(s);
if (_size + len > _capacity)
{
reserve(_size + len);
}
size_t end = _size;
while (pos <= end && end != npos)//当pos为0的时候,循环就退出不了,但pos减到-1的时候就当成了一个很大的数,所以再加一个条件判断
{
_str[end + len] = _str[end];
end--;
}
for (int i = 0; i <len; i++)
{
_str[pos++] = s[i];
}
_size += len;
return *this;
}
string& insert(size_t pos, size_t n, char c)//(从pos位置)
{
assert(pos <= _size);
if (_size + n > _capacity)
{
reserve(_size + n);
}
//挪动数据
size_t end = _size;
while (pos <= end&&end!=npos)//当pos为0的时候,循环就退出不了,但pos减到-1的时候就当成了一个很大的数,所以再加一个条件判断
{
_str[end + n] = _str[end];
end--;
}
//放数据
for (int i = 0; i < n; i++)
{
_str[pos++] = c;
}
_size += n;
return *this;
}
//==========erase函数的实现==============(从pos位置删除len长度的字符串)
string& erase(size_t pos = 0, size_t len = npos)
{
assert(pos <= _size);
if (pos + len >=_size)
{
_str[pos] = '\0';
_size = pos;
_str[_size] = '\0';
}
else
{
//覆盖数据
size_t end = pos+len;
while (end <= _size)
{
_str[pos++] = _str[end++];
}
_size -= len;
}
return *this;
}
//==========find的函数的实现=============
size_t find(const char* s, size_t pos = 0) const//从pos位置开始查找一个子串
{
assert(pos <= _size);
const char* ptr = strstr(_str+pos, s);
if (ptr)
{
return ptr - _str;
}
else
{
return npos;
}
}
size_t find(char c, size_t pos = 0) const//从pos位置开始查找一个字符
{
assert(pos <= _size);
for (int i = pos; i < _size; i++)
{
if (_str[i] == c)
{
return i;
}
}
return npos;
}
//=============substr函数的实现//获取子串
string substr(size_t pos = 0, size_t len = npos)//从pos位置查找长度为len的子串
{
assert(pos <= _size);
if (len==npos||pos + len > _size)
{
char* tmp = new char[_size - pos+1];
//strcpy(tmp, _str + pos);
memcpy(tmp, _str + pos, len + 1);
string Tmp(tmp);
return tmp;
}
else
{
char* tmp = new char[len + 1];
int j = 0;
for (int i = pos; i < pos + len; i++)
{
tmp[j++] = _str[i];
}
tmp[j] = '\0';
string Tmp(tmp);
return tmp;
}
}
//============operator=函数============
/*string& operator=(const string& s)
{
int len = strlen(s.c_str());
_str = new char[len + 1];
_size = len + 1;
_capacity = _size;
for (int i = 0; i < len; i++)
{
_str[i] = s[i];
}
_str[len] = '\0';
return *this;
}
string& operator= (const char* s)
{
int len = strlen(s);
_str = new char[len + 1];
_size = len + 1;
_capacity = _size;
for (int i = 0; i < len; i++)
{
_str[i] = s[i];
}
_str[len] = '\0';
return *this;
}*/
//string& operator=(const string& s)
//{
// string tmp(s);
// swap(tmp);
// return *this;
//}
string& operator=(string s)
{
swap(s);
return *this;
}
//============clear函数的实现=======
void clear()
{
_size = 0;
_str[_size] = '\0';
}
//=============析构函数===========
~string()
{
delete[] _str;
_str = nullptr;
_size = _capacity = 0;
}
//===============字符串比较函数================
bool operator<(const string& s)const
{
int ret=memcmp(_str, s._str, _size > s._size ? s._size : _size);
if (ret == 0)
{
if (s._size > _size)
{
return true;
}
}
return ret<0;
}
bool operator==(const string& s)const
{
return _size == s._size && memcmp(_str, s._str, _size)==0;
}
bool operator<=(const string& s)const
{
return (*this) < s || (*this) == s;
}
bool operator>(const string& s)const
{
return !((*this) <= s);
}
bool operator>=(const string& s)const
{
return !((*this) < s);
}
bool operator!=(const string& s)const
{
return !((*this) == s);
}
static size_t npos;
friend ostream& operator<<(ostream& cout, const string& s);
friend istream& operator>>(istream& cin, string& s);
private:
char* _str;
size_t _size;
size_t _capacity;
};
size_t string::npos = -1;
ostream& operator<<(ostream& cout, const string& s)
{
//cout << s.c_str();//这个大部分情况是可以的,但是中间有\0的情况不行,那么之前的strcpy函数都需要换,
//因为strcpy遇到\0就会停止,需要使用memcpy,按照字节赋值,string不是看\0结束的,而是看size结束的,strlen不需要换,他传进去就是字符串
for (int i = 0; i < s.size(); i++)
{
cout << s[i];
}
cout << endl;
return cout;
}
istream& operator>>(istream& cin, string& s)
{
s.clear();
char ch = cin.get();
const size_t N = 32;
char buff[N];//防止多次扩容,带来的消耗
int i = 0;
while (ch != ' ' && ch != '\n')
{
buff[i++] = ch;
if (i == N - 1)
{
buff[i] = '\0';
s += buff;
i = 0;
}
ch = cin.get();
}
buff[i] = '\0';
s += buff;
return cin;
}
}
Test.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include"string.h"
void test_string1()
{
xdh::string s1("hello world");
cout << s1.size() << endl;
cout << s1.capacity() << endl;
cout << "非const对象循环遍历:";
for (int i = 0; i < s1.size(); i++)
{
s1[i]+=1;
cout << s1[i] << " ";
}
cout << endl;
const xdh::string s2("hello C++");
cout << s2.size() << endl;
cout << s2.capacity() << endl;
cout << "const对象循环遍历:";
for (int i = 0; i < s2.size(); i++)
{
cout << s2[i] << " ";
}
cout << endl;
//=====迭代器的测试=====
//正向非const迭代器
xdh::string s3("hello linux");
cout << "正向非const迭代器:";
xdh::string::iterator it = s3.begin();
while (it != s3.end())
{
cout << *it<< " ";
it++;
}
cout << endl;
//正向const迭代器
cout << "正向const迭代器:";
const xdh::string s4("hello java");
xdh::string::const_iterator cit = s4.cbegin();
while (cit != s4.cend())
{
cout << (*cit) << " ";
cit++;
}
cout << endl;
反向非const迭代器
xdh::string s5("hello linux");
cout << "反向非const迭代器:";
xdh::string::reverse_iterator rit = s5.rbegin();
while (rit != s5.rend())
{
cout << (*rit) << " ";
rit--;
}
cout << endl;
反向const迭代器
cout << "反向const迭代器:";
const xdh::string s6("hello java");
xdh::string::const_reverse_iterator crit = s6.crbegin();
while (crit != s6.crend())
{
cout << (*crit) << " ";
crit--;
}
cout << endl;
//=======范围for=========(是基于迭代器的基础上)
cout << "范围for:";
xdh::string s7("hello sql");
for (char ch : s7)
{
cout << ch << " ";
}
cout << endl;
}
void test_string2()//测试push_back和append函数功能的
{
xdh::string s1("");
s1.push_back('n');
cout << s1.c_str() << endl;
xdh::string s2("hello world");
s2.append("nihao");
cout << s2.c_str() << endl;
xdh::string s3("hello world");
s3+='n';
cout << s3.c_str() << endl;
xdh::string s4("hello world");
s4+="nihaoma";
cout << s4.c_str() << endl;
}
void test_string3()//测试insert和erase函数功能的
{
//再pos位置插入n个字符
xdh::string s1("hello world");
s1.insert(0, 13, '#');
cout << s1.c_str() << endl;
xdh::string s2("hello world");
s2.insert(5, 13, '#');
cout << s2.c_str() << endl;
//再pos位置插入一个字符串
xdh::string s3("hello world");
s3.insert(0, "###");
cout << s3.c_str() << endl;
xdh::string s4("hello world");
s4.insert(5,"###");
cout << s4.c_str() << endl;
//再pos位置删除n个字符
xdh::string s5("hello world");
s5.erase(5,3);
cout << s5.c_str() << endl;
xdh::string s6("hello world");
s6.erase(0,3);
cout << s6.c_str() << endl;
xdh::string s7("hello world");
s7.erase(11, 3);
cout << s7.c_str() << endl;
}
void test_string4()//测试find和substr函数功能的
{
xdh::string url = "ftp://www.baidu.com/?tn=65081411_1_oem_dg";
size_t pos1 = url.find("://");
if (pos1 != xdh::string::npos)
{
xdh::string protocol = url.substr(0, pos1);
cout << protocol.c_str() << endl;
}
size_t pos2 = url.find('/', pos1 + 3);
if (pos2 != xdh::string::npos)
{
xdh::string domain = url.substr(pos1 + 3, pos2 - (pos1 + 3));
xdh::string uri = url.substr(pos2 + 1);
cout << domain.c_str() << endl;
cout << uri.c_str() << endl;
}
}
void test_string5()//测试拷贝构造和赋值运算符
{
const xdh::string s1("xudonghui");
const xdh::string s2(s1);
cout << s1.c_str() << endl;
cout << s2.c_str() << endl;
xdh::string s3("xudonghui");
xdh::string s4 = s3;
cout << s3.c_str() << endl;
cout << s4.c_str() << endl;
xdh::string s5("xu");
xdh::string s6("niadia");
s5 = s6;
cout << s5.c_str() << endl;
cout << s6.c_str() << endl;
xdh::string s7("xu");
s7 = "nihao";
;
cout << s7.c_str() << endl;
}
void test_string6()//测试输入输出函数
{
xdh::string s1("hello"), s2;
cin >> s1 >> s2;
cout << s1 << s2;
}
void test_string7()
{
xdh::string s1("hello world");
s1.resize(20,'9');
cout << s1;
}
void test_string8()
{
xdh::string s1("awqdq ");
xdh::string s2("hello");
cout << (s1 < s2) << endl;
}
void test_string9()
{
xdh::string s1("awqdq ");
xdh::string s2("hello");
s1 = s2;
cout << s1 << s2;
}
int main()
{
/*test_string1();
cout << endl;
test_string2();
cout << endl;
test_string3();
cout << endl;
test_string4();
cout << endl;
test_string5();
cout << endl;*/
test_string9();
return 0;
}
大家自己看着实现一下