string& insert(size_t pos, char* str)
{
assert(pos < _size);
int len = strlen(str);
if (len + _size > _capacity)
{
reserve(len + _size);
}
int end=_size;
while (end >= pos)
{
_str[end + pos] = _str[end];
--end;
}
strncpy(_str + pos, str, len);
_size += len;
return *this;
}
在第0个位置插入时会发生错误。
pos 无符号
end 有符号
为了防止截断有符号会转为无符号,所以应在pos前加(int)pos
void insert(size_t pos, char ch)
{
assert(pos < _size);
if (_size == _capacity)
{
size_t newcapacity = _capacity == 0 ? 2 : _capacity * 2;
reserve(newcapacity);
}
int end = _size;
while (end >= pos)
{
_str[end+1] = _str[end];
--end;
}
_str[pos] = ch;
++_size;
}
与strcpy相比可以指定拷贝的长度。
string& erase(size_t pos, size_t len = string::npos)
{
if (len >= _size - pos)
{
_str[pos] = 0;
}
else
{
int i = pos + len;
while (i <= _size)
{
_str[i - len] = _str[i];
i++;
}
_size -= len;
//_str[_size] = 0;---> i < _size
}
return *this;
}
resize应分三种情况,考虑n与_size的情况
void resize(int n, char ch = '\0')
{
if (n < _size)
{
_str[n] = '\0';
_size = n;
}
else
{
if (n > _capacity)
reserve(n);
for (int i = _size; i < n; i++)
_str[i] = ch;
_size = n;
_str[_size] = 0;
}
}
size_t find(char ch, size_t pos = 0)
{
for (int i = pos; i < _size; ++i)
{
if (ch == _str[i])
return i;
}
return string::npos;
}
size_t find(const char* str, size_t pos = 0)
{
char*p=strstr(_str, str);
if (p == nullptr) return string::npos;
else return p - _str;
}
istream& operator>>(istream& in, string& s)
{
int i;
for (; ;)
{
char ch;
//in >> ch;
ch = in.get();
if (ch==' '||ch == '\n')
break;
else
s += ch;
}
return in;
}
string(const string& s)
:_str(nullptr)
{
string tmp(s);
swap(_str, tmp._str);
}
_str应置空,随机值析构时会报错。
string& operator=(const string& s)
{
if (this != &s)
{
string tmp(s);
swap(_str, tmp._str);
}
return *this;
}
tmp是临时对象出了作用域会调析构函数。赋值不存在_str为空的情况。
string& operator=(string& s)
{
swap(_str, s._str);
return *this;
}