一.c++的string库
在C++中,std::string
是标准模板库(STL)中用于处理字符串的一个非常强大的类。它提供了丰富的成员函数和操作符重载,使得字符串的创建、修改、拼接、比较等操作变得非常方便。
二.构造函数和析构函数
1.标准库提供的构造函数的用法
2.几种构造函数和拷贝构造函数的模拟实现
(1)
string()
:_size(0)
,_capacity(0)
,_str(new char [1])//注意这里怎么给
{
_str[0] = '\0';
}
(2)
string(const char* str = " ")
{
_size = strlen(str);
_capacity = _size;
_str = new char[_capacity + 1];
memcpy(_str, str, _size + 1);
}
string(const char* str = nullptr)
{
_size = strlen(str);
_capacity = _size;
_str = new char[_capacity + 1];
memcpy(_str, str, _size + 1);
}
(3)
//拷贝构造函数
string(const string& str)
{
_str = new char[str._capacity ];
memcpy(_str, str._str, _size + 1);
_size = str._size;
_capacity = str._capacity;
}
(4)
//析构函数
~string()
{
delete[] _str;
_str = nullptr;
_size = _capacity = 0;
}
3.注意和区分三种写法
三.和容量相关的函数
1.常用函数的用法
(1)返回字符串当中字符的数量
(2)返回分配给字符串的内存容量
(3)内存分配函数
2.函数的模拟实现
(1)size () 和 capacity ()
//长度和容量获取
size_t size()const
{
return _size;
}
size_t capacity()const
{
return _capacity;
}
(2)reserve()
void reserve(size_t n)
{
if (n > _capacity)
{
char* temp = new char[n];
memcpy(temp, _str, _size + 1);
delete[] _str;
_str = temp;
_capacity = n;
}
}
(3)resize()
void resize(size_t n, char ch = '\0')
{
if (n > _size)
{
reserve(n);
for (int i = _size; i++; i < n)
{
_str[i] = ch;
}
_size = n;
_str[_size] = '\0';
}
else
{
_size = n;
_str[_size] = '\0';
}
}
四.运算符重载
1.赋值运算符重载 =
(1)赋值运算符重载的使用
(2)赋值运算符重载的模拟实现
void swap(string& temp)
{
std::swap(_size,temp._size);
std::swap(_capacity, temp._capacity);
std::swap(_str, temp._str);
}
string& operator=(string& temp)
{
swap(temp);
return *this;
}
2.下标访问运算符重载 【】
(1)重载运算符的使用
(2)下标访问运算符重载的实现
char& operator[] (size_t n)
{
assert(n < _size);
return _str[n];
}
const char& operator[] (size_t n)const
{
assert(n < _size);
return _str[n];
}
五.字符的拼接
1.单个字符的尾插
(1)push_back的使用
(2)push_back的模拟实现
void push_back(char ch)
{
if (_size == _capacity)
{
// 2倍扩容,每个编译器的扩容机制是不一样的
reserve(_capacity == 0 ? 4 : _capacity * 2);
}
_str[_size] = ch;
++_size;
_str[_size] = '\0';
}
2.字符串的尾插
(1)append的使用
(2)append的模拟实现
void append(const char* str)
{
size_t len = strlen(str);
if (_size + len > _capacity)
{
//每个编译器的扩容机制不同,假设编译器这样扩容
reserve(_size+len+1);
}
memcpy(_str + _size, str, len+1);
_size += len;
}
void append(const string& str)
//先处理容量问题再改变_size
{
size_t length =str._size;//拼接字符串的长度
if (length + _size > _capacity)
{
reserve(_size + length + 1);
}
memcpy(_str + _size, str._str, length + 1);
_size += length;
}
3.使用运算符重载实现尾插(即字符串拼接)
(1)+=的使用
(2)+=的简单模拟实现
string& operator+=(char ch)
{
push_back(ch);
return *this;
}
string& operator+=(const char* str)
{
append(str);
return *this;
}
六.字符串的插入删除
1.字符串的插入
(1)常见的几种insert()用法
(2)两个insert函数的模拟实现
string& insert(size_t pos, size_t n, char ch)
{
assert(pos <= _size);
//扩容
if (_size + n > _capacity)
{
reserve(_size + n + 1);
}
//挪动数据
size_t end = _size;
while (end >= pos && end != std::string::npos)
{
_str[end + n] = _str[end];
--end;
}
//单个字符的插入
for (size_t i = 0; i < n; i++)
{
_str[pos + i] = ch;
}
//_size的改变
_size += n;
return *this;
}
string& insert(size_t pos, const char* str)
{
assert(pos <= _size);
//扩容
size_t len = strlen(str);
if (_size + len > _capacity)
{
reserve(_size + len + 1);
}
//挪动数据
size_t end = _size;
while (end >= pos && end != std::string::npos)
{
_str[end + len] = _str[end];
--end;
}
//字符串的添加
for (size_t i = 0; i < len; i++)
{
_str[pos + i] = str[i];
}
//_size的改变
_size += len;
return *this;
}
2.字符串的删除
(1)erase()常见的用法
(2)erase()一种重载形式的模拟实现
string& erase(size_t pos, size_t len = std::string::npos)//pos是下标
{
assert(pos <= _size);
//后面全部删除极即为截断
if (len == std::string::npos || 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;
}
七.字符串的查找
(1)find()函数的使用
(2)find()的模拟实现
size_t find(const char* str, size_t pos = 0)
{
assert(pos < _size);
const char* ptr = strstr(_str + pos, str);
//strstr的用法:strstr(1,2)返回2在1第一次出现的地址
if (ptr)
{
return ptr - _str;
}
else
{
return std::string::npos;
}
}
八.字符串的截取
(1)substr的用法
(2)substr的模拟实现
string substr(size_t pos = 0, size_t len = std::string::npos)
{
assert(pos < _size);
//得到需要截取的字符串长度
size_t n = len;
if (len == std::string::npos || pos + len > _size)
{
n = _size - pos;//如果超出范围重新调整截取字串的长度
}
string tmp;
tmp.reserve(n);//构造新的字串
for (size_t i = pos; i < pos + n; i++)
{
tmp += _str[i];//新字串得到数据
}
return tmp;
}