cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string.h>
#include<assert.h>
using namespace std;
namespace xyt
{
class string
{
public:
typedef char* iterator;
typedef const char* const_iterator;
string()
:
_size (0)
,_capacity(4)
,_str (new char[_capacity+1])
{
_str[0] = '\0';
}
string(const string& str)
{
_size = str._size;
_capacity = str._capacity;
_str=new char[_capacity + 1];
memcpy(_str, str._str,str._size);
_str[_size] = '\0';
}
string(const char* s)
{
if (s == nullptr)
{
s = " ";
}
size_t len = strlen(s);
_size = len;
_capacity = len;
_str = new char[_capacity + 1];
strcpy(_str, s);
_str[_size] = '\0';
}
~string()
{
delete [] _str;
_str = nullptr;
}
void reserve(size_t newcapacity)
{
if (newcapacity > _capacity)
{
char* tmp = new char[newcapacity + 1];//扩容
// 替代循环的等价写法
memcpy(tmp, _str, _size + 1); // 拷贝 _size+1 个字节(包括末尾的 '\0')
_capacity = newcapacity;
delete[] _str;
_str = tmp;
}
}
void push_back(char c)
{
if (_size >= _capacity)
{
reserve(_capacity * 2);
}
_str[_size++] = c;
_str[_size] = '\0';
}
void append(const char* s)
{
assert(s);
if (s == " ")
{
return;
}
size_t len = strlen(s);
if (_size + len > _capacity)
{
reserve(_size + len);
}
strcpy(_str + _size, s);
_size += len;
}
iterator begin()
{
return _str;
}
iterator end()
{
return _str + _size;
}
const_iterator begin()const
{
return _str;
}
const_iterator end()const
{
return _str + _size;
}
char& operator[](size_t pos)
{
if (pos >= _size)
{
// 抛 out_of_range 异常,上层可捕获
throw std::out_of_range("xyt::string::operator[]: pos out of range");
}
return _str[pos];
}
const char& operator[](size_t pos)const
{
if (pos >= _size)
{
// 抛 out_of_range 异常,上层可捕获
throw std::out_of_range("xyt::string::operator[]: pos out of range");
}
return _str[pos];
}
size_t size()
{
return _size;
}
string& operator+= (const char* s)
{
append(s);
return *this;
}
string& operator+= (char c)
{
push_back(c);
return *this;
}
string& insert( size_t n, char c,size_t pos = npos )
{
if (pos >= _size || pos == npos)
{
for (size_t i = 0; i < n; i++)
{
push_back(c);
}
}
else
{
if (n + _size > _capacity)
{
reserve(n + _size);
}
for (size_t i = n + _size; i > pos+n; i--)
{
_str[i] = _str[i - n];
}
for (size_t i = 0; i < n; i++)
{
_str[pos + i] = c;
}
}
_size += n;
return *this;
}
string& insert( const char* s, size_t pos=npos )
{
size_t len = strlen(s);
if (pos >= _size || pos == npos)
{
append(s);
}
else
{
if (len + _size > _capacity)
{
reserve(len + _size);
}
for (size_t i = _size + len; i > pos + len; i--)
{
_str[i] = _str[i - len];
}
for (size_t i = 0; i < len; i++)
{
_str[pos + i] = s[i];
}
}
_size += len;
return *this;
}
string& erase(size_t pos = 0, size_t len = npos)
{
if (pos >= _size) {
return *this;
}
if (len==npos ||pos + len >= _size)
{
_str[pos] = '\0';
_size = pos;
}
else
{
for (size_t i = 0; i < _size - pos - len; i++)
{
_str[pos + i] = _str[pos + i + len];
}
_size -= len;
_str[_size]='\0';
}
return *this;
}
size_t find(const string& str, size_t pos = 0) const
{
const char* sub_str = str._str;
if (sub_str == nullptr)
{
sub_str = "";
}
size_t len = strlen(sub_str);
if (len == 0)
{
return (pos <= _size) ? pos : npos;
}
if (pos >= _size || pos + len > _size)
{
return npos;
}
for (size_t i = pos; i <= _size - len; i++)
{
int tmp = 0;
for (size_t j = 0; j < len; j++)
{
if (_str[i + j] != sub_str[j])
{
tmp = 1;
break;
}
}
if (tmp == 0)
{
return i;
}
}
return npos;
}
string substr(size_t pos = 0, size_t len = npos)const
{
string str;
// 1. 检查起始位置是否有效
if (pos >= _size)
{
// 返回空字符串
str._size = 0;
str._capacity = 0;
str._str = new char[1];
str._str[0] = '\0';
return str;
}
// 2. 计算实际长度
size_t actual_len = len;
if (len == npos || pos + len > _size)
{
actual_len = _size - pos;
}
// 3. 处理长度为0的情况
if (actual_len == 0)
{
str._size = 0;
str._capacity = 0;
str._str = new char[1];
str._str[0] = '\0'; // 修正:应该是 str._str
return str;
}
// 4. 分配内存并复制
str._size = actual_len;
str._capacity = actual_len;
str._str = new char[actual_len + 1];
if (len == npos || pos + actual_len == _size)
{
// 情况1:复制到字符串末尾,可以用 strcpy
strcpy(str._str, _str + pos);
}
else
{
// 情况2:复制指定长度,需要用 strncpy 并手动添加 \0
strncpy(str._str, _str + pos, actual_len);
str._str[actual_len] = '\0'; // 必须手动添加结束符
}
return str;
}
void swap(string& tmp)
{
std::swap(this->_capacity,tmp._capacity);
std::swap(this->_size, tmp._size);
std::swap(this->_str, tmp._str);
}
string& operator=(string tmp)//非常屌的写法
{
swap(tmp);
return *this;
}
bool operator==(const string& s)
{
return _size == s._size ? (memcmp(_str, s._str, _size)) == 0 : false;
}
bool operator<(const string& s)
{
size_t _size1 = _size;
if (_size > s._size)
{
_size1 = s._size;
}
if (memcmp(_str, s._str, _size1) < 0)
{
return true;
}
else if ((memcmp(_str, s._str, _size1) == 0) && s._size > _size)
{
return true;
}
else
{
return false;
}
}
bool operator<=(const string& s)
{
return (*this == s) || (*this < s);
}
bool operator>(const string& s)
{
return !(*this <= s);
}
bool operator>=(const string& s)
{
return !(*this < s);
}
friend ostream& operator<<(ostream& out, const string& s);
friend istream& operator>>(istream& in, string& s);
void clear()
{
_size = 0;
_str[0] = '\0';
}
private:
size_t _size;
size_t _capacity;
char* _str;
public:
static size_t npos;
};
ostream& operator<<(ostream& out, const string& s)
{
for (size_t i = 0; i < s._size; i++)
{
out << s[i];
}
return out;
}
istream& operator>>(istream& in, string& s)
{
s.clear();
char ch = in.get();
int i = 0;
while (ch!=EOF&&(ch=='\t'||ch=='\r'||ch == ' ' || ch == '\n'))
{
ch = in.get();
}
char buff[128] = { '\0' };
while (ch != ' ' && ch != '\n')
{
buff[i++] = ch;
if (i == 127)
{
buff[i] = '\0';
s += buff;
i = 0;
}
ch = in.get();
}
if (i != 0)
{
buff[i] = '\0';
s += buff;
}
return in;
}
size_t xyt::string::npos = -1;
}
以上代码是string类的模拟实现,实现了string的最常用最基本的成员函数。
这里有一个点:string类的结束条件并不在于'\0',而是在于size的大小,所以,在遇到string的拷贝或扩容时,我们不能用strcpy或strncpy,因为这两个函数的结束条件都是遇到'\0'为之,所以,我们要使用memcpy。