分为两种情况:
(1)+= 1个字符 ,使用push_back插入
(2)+= 字符串,使用append追加到字符串末尾
1. //+= 1个字符 2. string& operator+= (char c) 3. { 4. push_back(c);//尾插字符 5. return *this; 6. } 7. 8. //+= 字符串 9. string& operator+= (const char* str) 10. { 11. append(str);//拼接字符串 12. return *this; 13. }
在指定位置插入字符:
(1)判断是否需要增容
(2)将pos位至字符串末尾的字符都向后挪一个位置
(3)将要插入的字符插入到pos位
(4)更新_size
1. //insert插入一个字符 2. string& insert(size_t pos, const char ch) 3. { 4. assert(pos <= _size);//pos必须小于等于字符串长度 5. 6. if (_size == _capacity) 7. { 8. reserve(2 * _capacity);//如果满了就增容 9. } 10. 11. size_t end = _size + 1; 12. while (end > pos)//将pos至_size之间的字符依次向后挪动一个位置,来腾出pos位置 13. { 14. _str[end] = _str[end - 1]; 15. end--;//end为0时,因此end类型应为int,那么end--就为-1,pos为无符号数,不满足循环条件,退出循环 16. //但如果end类型为size_t,那么end为0时,end--就为-1,在内存中存储为无符号数(-1补码全1),满足循环条件,永远无法退出循环 17. } 18. 19. _str[pos] = ch;//pos位置插入ch 20. _size++;//更新_size 21. 22. return *this; 23. }
删除字符,len为要删除的字符个数,分两种情况:
(1)从pos到字符串末尾的字符个数<要删除的字符个数,说明this._str长度不够删,那pos之后全都被删完了,直接将pos位置'\0',_size更新为pos即可。
(2)从pos到字符串末尾的字符个数≥要删除的字符个数,说明this._str长度够删,但是剩余的字符需要向前挪动len位
1. //erase 删除字符 2. string& erase(size_t pos, size_t len = npos) 3. { 4. assert(pos < _size); 5. 6. size_t leftLen = _size - pos;//从pos位置到字符串结束的字符长度 7. if (leftLen < len)//1.pos之后的字符全部删掉 8. { 9. _str[pos] = '\0'; 10. _size = pos; 11. } 12. else//2.pos之后的字符删掉一部分,没删完的部分要挪到pos位置 13. { 14. strcpy(_str + pos, _str + pos + len); 15. _size -= len; 16. } 17. return *this; 18. }
分为查找字符和查找字符串
1. //查找字符 2. size_t find(char ch, size_t pos = 0) 3. { 4. assert(pos < _size); 5. for (size_t i = 0; i < _size; i++) 6. { 7. if (_str[i] == ch) 8. { 9. return i;//找到就返回字符所在位置 10. } 11. } 12. return npos;//没找到就返回-1 13. }
1. //查找字符串(子串) 2. size_t find(const char* str, size_t pos = 0) 3. { 4. assert(pos < _size); 5. const char* ret = strstr(_str + pos, str); 6. 7. if (ret) 8. { 9. return ret - _str;//计算str与_str的偏移量,即str在_str中的下标 10. } 11. else 12. { 13. return npos;//没找到就返回-1 14. } 15. }
字符串比较,只需要实现>和==,剩余的可以用这两个实现重载
1. bool operator>(const string& s) 2. { 3. return strcmp(_str, s._str) < 0; 4. }
1. bool operator==(const string& s) 2. { 3. return strcmp(_str, s._str) == 0; 4. }
20.operator>=
1. bool operator>=(const string& s) 2. { 3. return (*this > s) || (*this == s); 4. }
1. bool operator<(const string& s) 2. { 3. return !(*this >= s); 4. }
1. bool operator<=(const string& s) 2. { 3. return !(*this > s); 4. }
1. bool operator!=(const string& s) 2. { 3. return !(*this == s); 4. }
将字符串清空
1. void clear() 2. { 3. _size = 0; 4. _str[0] = '\0'; 5. }
输出重载<<让string直接输出打印,像内置类型一样,用范围for就可以实现
1. ostream& operator<<(ostream& out, const string& s) 2. { 3. for (auto ch: s) 4. { 5. out << s; 6. } 7. return out; 8. }