string 类的实现
通过http://www.cplusplus.com/reference/这个网站可以查到一些C++库的使用方法,只是都是英文,是一个大的挑战
本文简单介绍下STL 中的string的基本操作
成员变量
private:
char* _str; //存放字符串
size_t _size; //当前有效字符串的数量
size_t _capacity; //能最大存储的有效字符串数量,不包括'\0'
static size_t npos;
- npos:代表着无符号数据的最大值,也就是
[4294967295]
默认成员函数
构造函数
//构造函数
my_string(const char* str = "")
{
//防止传入的字符串就是空指针,strlen和strcpy不能访问空指针
if(nullptr == str)
{
_size = 0;
_str = nullptr;
}
else
{
_size = strlen(str);
_str = new char[_capacity + 1];//预留'\0'的位置
strcpy(_str, str);
}
_capacity = _size;
}
析构函数
//析构函数
~my_string()
{
delete[] _str;
_str = nullptr;
_size = _capacity = 0;
}
拷贝构造
//拷贝构造
my_string(const my_string& s)
{
/*
//浅拷贝
_str = s._str;
_size = s._size;
_capacity = s._size;
*/
//深拷贝
_str = new char[s._size + 1];//多开一个
strcpy(_str, s._str);
_size = s._size;
_capacity = s._size;
}
运算符重载
赋值运算符
//赋值运算符重载
my_string& operator=(const my_string& s)
{
if (this != &s)
{
delete[] _str;
_str = new char[s._size + 1];
strcpy(_str, s._str);
_size = s._size;
_capacity = s._capacity;
}
return *this;
}
[ ]运算符重载
//[]运算符重载
char& operator[](size_t pos)
{
assert(pos < _size);//不能越界
return _str[pos];
}
+= 运算符重载
my_string& operator+=(const my_string& s)
{
//如果空间不够,就扩容
reserve(_size + s._size);
strncpy(_str + _size, s._str, s._size + 1);//得要把末尾的'\0'也一起拷贝过来
_size += s._size;
return *this;
}
my_string& operator+=(const char* str)
{
size_t len = strlen(str);
reserve(_size + len);
strncpy(_str + _size, str, len + 1);//得要把末尾的'\0'也一起拷贝过来
_size += len;
return *this;
}
my_string& operator+=(const char s)
{
//如果空间不够,就扩容
reserve(_size + 1);
_str[_size++] = s;
_str[_size] = '\0';
return *this;
}
cout运算符重载
在类的前面需要加友元,函数实现在类的外面
friend ostream& operator<<(ostream& out, const my_string& s);
ostream& operator<<(ostream& out, const my_string& s)
{
cout << s._str << endl;
return out;
}
cin运算符重载
在类的前面需要加友元,函数实现在类的外面
friend istream& operator>>(istream& in, my_string& s);
istream& operator>>(istream& in, my_string& s)
{
//不能简单的使用cin,因为此时_str的空间不是new开辟出来的,在析构的时候会有问题
while (1)
{
char ch = in.get();
if (ch == ' ' || ch == '\n')
break;
s += ch;
}
return in;
}
getline 获取一行数据
在类的前面需要加友元,函数实现在类的外面
friend istream& getline(istream& in, my_string& s);
istream& getline(istream& in, my_string& s)
{
while (1)
{
char ch = in.get();
if (ch == '\n')
break;
s += ch;
}
return in;
}
比较运算符重载
bool operator<(const my_string& s)
{
return strcmp(_str, s._str) < 0;
}
bool operator==(const my_string& s)
{
return strcmp(_str, s._str) == 0;
}
bool operator<=(const my_string& s)
{
return *this < s || *this == s;
}
bool operator>(const my_string& s)
{
return !(*this <= s);
}
bool operator>=(const my_string& s)
{
return !(*this < s);
}
bool operator!=(const my_string& s)
{
return !(*this == s);
}
Modifiers修饰符
push_back 尾插
void push_back(char c)
{
reserve(_size + 1);//判断是否满了
_str[_size++] = c;
_str[_size] = '\0';//记得结尾加'\0'
}
append追加
my_string& append(const my_string& s)//追加一个类
{
*this += s;
return *this;
}
my_string& append(const char* c)//追加一个字符串
{
my_string s(c);
*this += s;
return *this;
}
my_string& append(const char c)//追加一个字符
{
this->append(c);
return *this;
}
insert 插入
void insert(size_t pos, char c)//插入一个字符
{
assert(pos < _size);
reserve(_size + 1);
memmove(_str + pos + 1, _str + pos, _size - pos);
_str[pos] = c;
_size++;
_str[_size] = '\0';
}
void insert(size_t pos, const char* str)//插入字符串
{
assert(pos < _size);
int len = strlen(str);
reserve(pos + _size);
memmove(_str + pos + len, _str + pos, _size - pos);
strncpy(_str + pos, str, len);//不能用strcpy,防止吧'\0'拷贝到中间位置
_size += len;
_str[_size] = '\0';
}
erase 消除
void erase(size_t pos, size_t len = npos)
{
assert(pos < _size);
if (_size - pos < len)//消除pos后面所有字符
{
_str[pos] = '\0';
_size = pos;
}
else//消除部分字符
{
memmove(_str + pos, _str + pos + len, _size - (pos + len));
_size -= len;
_str[_size] = '\0';
}
}
capacity 容量
size 返回字符串大小
size_t size()
{
return _size;
}
capacity 返回字符串容量
size_t capacity()
{
return _capacity;
}
reserve 增加容量
void reserve(size_t n)
{
//如果n小于容量,则不做任何改变
if (n > _capacity)
{
char* newstr = new char[n + 1];//预留'\0'的空间
strcpy(newstr, _str);
delete[] _str;
_str = newstr;
_capacity = n;
}
}
resize 固定容量
void resize(size_t n, char c = '\0')
{
//n小于当前字段长度,进行删除
if (n < _size)
{
_size = n;
_str[_size] = '\0';
}
else //大于当前字段长度,进行插入
{
if (n > _capacity)//空间是否足够
reserve(n);
//插入
for (size_t i = _size; i < n; i++)
_str[i] = c;
_size = n;
_str[_size] = '\0';
}
}
clear 清理函数
void clear()
{
_size = 0;
}
empty 判空
bool empty()const
{
return _size ? true : false;
}
Iterators 迭代器
本质
typedef char* iterators;
begin
iterators begin()
{
return _str;
}
end
iterators end()
{
return _str + _size;
}
String operations
find 查找函数
size_t find(const char* str, size_t pos = 0)
{
const char* p = strstr(_str + pos, str);
return (p == nullptr) ? npos : (p - _str);
}
size_t find(const my_string& s, size_t pos = 0)
{
return find(s._str, pos);
}
size_t find(const char& ch, size_t pos = 0)
{
for (size_t i = pos; i < _size; i++)
{
if (_str[i] == ch)
return i;
}
return npos;
}
substr 截取字符串
my_string substr(size_t pos = 0, size_t len = npos)const
{
my_string ret("");
for (size_t i = pos; i < len; i++)
{
ret += _str[i];
}
cout << ret << endl;
return ret;
}