#pragma once
#include<iostream>
#include<assert.h>
using std::cout;
using std::endl;
using std::cin;
using std::ostream;
using std::exception;
using std::istream;
namespace sxh
{
class string
{
public:
typedef char* iterator;
static const size_t nops = -1;
iterator begin()
{
return _str;
}
iterator end()
{
return _str+_size;
}
string(const char* str = "") :_str(new char[strlen(str)+1]), _size(strlen(str)), _capacity(_size)
{
strcpy(_str, str);
}
/*string(const string& str):_str(new
char[str._capacity]),
_size(str._size),
_capacity(str._capacity)
{
strcpy(this->_str, str._str);
}*/
string(const string& str)
{
//我在vs2022中模拟list测试list<string> 时,不知道为什么在list构造函数初始化列表中
//使用data(sting())时会崩溃.调试后发现data里的数据和正常调用时的数据不同,data不是
//全零,且_size和_capacity显
//示最大值,_str的地址显示非零的随机地址
//之后拷贝构造结束后释放temp时,会直接程序崩溃
//故我在开始时将_str设为空
this->_str = nullptr;
string temp(str._str);
this->swap(temp);
}
~string()
{
delete[] this->_str;
_str = nullptr;
_size = 0;
_capacity = 0;
}
//string function
void swap(string& s1)
{
std::swap(this->_str, s1._str);
std::swap(this->_size, s1._size);
std::swap(this->_capacity, s1._capacity);
}
void reserve(unsigned int capacity)
{
char* temp = new char[capacity + 1];
if (this->_str != nullptr)
{
strcpy(temp, this->_str);
delete[] this->_str;
this->_str = temp;
}
else
{
temp = nullptr;
_str = temp;
}
_capacity = capacity;
}
void push_back(const char ch)
{
if (_size == _capacity)
{
_capacity = _capacity == 0 ? 2 : _capacity * 2;
reserve(_capacity);
}
_str[_size] = ch;
_str[_size + 1] = '\0';
++_size;
}
void append(const char* str)
{
if (this->_size + strlen(str) > this->_capacity)
{
_capacity = _size + strlen(str);
reserve(_capacity);
}
strcpy(_str + _size, str);
_size += strlen(str);
_str[_size] = '\0';
}
size_t size()const
{
return _size;
}
size_t size()const
{
return _capacity;
}
string& insert(size_t pos,const string& str)
{
assert(pos <= _size);
if (this->_capacity < this->_size + str._size)
{
_capacity = _capacity * 2 + str._size;
reserve(_capacity);
}
int length = this->_size;
while (length >=(int)pos)
{
this->_str[length + str._size] = this->_str[length];
length--;
}
for (size_t i = 0; i < str._size; ++i)
{
this->_str[pos] = str[i];
pos++;
}
this->_size += str._size;
return *this;
}
void insert(size_t pos, size_t count,const char ch)
{
assert(pos <= _size);
if (this->_capacity <= this->_size+count)
{
reserve(_size+count);
}
int length = this->_size;
while (length >= (int)pos)
{
this->_str[length + count] = this->_str[length];
length--;
}
for (size_t i = 0; i < count; ++i)
{
this->_str[pos] = ch;
pos++;
}
this->_size += count;
if (this->_str[_size] != '\0')
this->_str[_size] = '\0';
}
string& insert(size_t pos, const char* str)
{
assert(pos <= _size);
size_t len = strlen(str);
if (this->_capacity < this->_size + len)
{
_capacity = _capacity * 2 + len;
reserve(_capacity);
}
int length = this->_size;
while (length >= (int)pos)
{
this->_str[length + len] = this->_str[length];
length--;
}
for (size_t i = 0; i < len; ++i)
{
this->_str[pos] = str[i];
pos++;
}
this->_size += len;
if (this->_str[_size] != '\0')
this->_str[_size] = '\0';
return *this;
}
//resize(19)
//"helloworld"
void resize(size_t newsize,char ch = '\0')
{
if (newsize > this->_capacity)
{
reserve(_capacity+newsize);
}
//resize(2)
if (newsize < _size)
{
_str[newsize] = '\0';
_size = newsize;
}
else
{
for (size_t i = _size; i < newsize; ++i)
{
_str[i] = ch;
}
_size = newsize;
_str[_size] = '\0';
}
}
void erase(size_t pos, size_t len = nops)
{
assert(pos < _size);
if (len >= _size - pos)
{
_str[pos] = '\0';
_size = pos;
}
else
{
for (size_t i = pos + len; i < _size; ++i)
{
_str[pos] = _str[i];
++pos;
}
_size -= len;
}
}
size_t find(const char ch,const size_t pos = 0)
{
for (size_t i = pos; i < _size; i++)
{
if (_str[i] == ch)
{
return i;
}
}
return nops;
}
size_t find(const char* ch, const size_t pos = 0)
{
for (size_t i = pos; i < _size; ++i)
{
if (_str[i] == *ch)
{
ch++;
if (*ch == '\0')
{
return i;
}
}
}
return nops;
}
//string operator function
/*string& operator=(const string& str)
{
this->_str = new char[str._capacity];
this->_size = str._size;
this->_capacity = str._capacity;
strcpy(this->_str, str._str);
return *this;
}*/
string& operator=(string& str)
{
this->swap(str);
return *this;
}
string& operator=(const char* str)
{
this->append(str);
return *this;
}
char operator[](size_t i)const
{
return _str[i];
}
char operator[](const int i)const
{
return _str[i];
}
string& operator+=(const char* str)
{
this->append(str);
return *this;
}
string& operator+=(const char str)
{
this->push_back(str);
return *this;
}
void getline(istream& in)
{
while (1)
{
char ch;
ch = in.get();
if (ch == '\n')
{
break;
}
*this += ch;
}
}
friend ostream& operator<<(ostream& os, const string& str);
friend istream& operator>>(istream& is, string& str);
private:
char* _str;
size_t _size;
size_t _capacity;
};
ostream& operator<<(ostream& os, const string& str)
{
for (size_t i = 0; i < str.size(); ++i)
{
os << str[i];
}
return os;
}
istream& operator>>(istream& in,string& str)
{
while (1)
{
char ch;
ch = in.get();
if (ch == '\n'|| ch == '\0')
{
break;
}
str += ch;
}
return in;
}
}
C++ string容器模拟实现(初阶,不含分配器)
于 2023-12-28 17:01:47 首次发布