STL string

 

定义

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;
}