定义
C++中定义string类, 用以支持字符串各种操作
实现
C++ string 基于动态数组和内存管理, 其底层结构可以视为字符数组 + 管理机制
内部数据结构
struct std::string {
// 指向存储字符的动态分配内存的指针
char* _data;
// 当前字符串大小(字符数量)
size_t _size;
// 已分配内存大小(容量)
size_t _capacity;
};
容量分配
当字符串长度增加超过 _capacity 时, string 会使用 realloc 增大内存, 大多数实现中, 扩容策略是按2倍扩容(类似 vector)
小对象优化
短字符串(通常15字节以下)可以在栈中直接存储, 不使用 _data 指针动态分配内存, 从而减少内存分配和回收的开销
关键操作
构造函数
string::string(const char* s) {
_size = strlen(s);
_capacity = _size;
// 额外1个字节存储 '\0'
_data = new char[_size + 1];
memcpy(_data, s, _size);
// 以 '\0' 结束字符串
_data[_size] = '\0';
}
析构函数
string::~string() {
delete[] _data;
}
拷贝赋值操作
string& string::operator=(const string& other) {
if (this != &other) {
// 释放原内存
delete[] _data;
_size = other._size;
_capacity = other._capacity;
_data = new char[_capacity + 1];
// 包括 '\0'
memcpy(_data, other._data, _size + 1);
}
return *this;
}
接口
查找
find
- 示例, 查找子串
#include <iostream>
#include <string>
int main() {
std::string s1 = "abcdef";
std::string s2 = "abc";
int sum = 0;
for(int i = 0; i < s1.size(); i++){
if(s1.find(s2, i) != std::string::npos){
sum++;
}
}
std::cout << sum << std::endl;
return 0;
}
转换
c_str
返回一个指向C字符串指针常量
const char* c_str() const
- 示例, std::string转换
#include <iostream>
int main() {
std::string name = "DMJCB";
const char* name1 = name.c_str();
// DMJCB
printf("%s\n", name1);
return 0;
}
getline
读取一行可含空格字符串
std::string str;
getline(std::cin, str);
删除
erase
#include <iostream>
#include <string>
int main() {
std::string s = " 123 456237";
int index = 3;
int length = 1;
s.erase(index, length);
std::cout << s << std::endl;
return 0;
}