C++ 中的 std::string 类是标准库提供的字符串类,相比 C 风格字符串更安全、更易用、功能更强大。它是现代 C++ 中处理字符串的首选方式。

string 类的基础

包含头文件和基本声明

#include <iostream>
#include <string>
#include <vector>
 
int main() {
    // 1. 默认构造函数 - 空字符串
    std::string str1;
    std::cout << "str1: '" << str1 << "', length: " << str1.length() << std::endl;
    
    // 2. 从 C 风格字符串构造
    std::string str2("Hello World");
    std::string str3 = "Hello C++";
    
    // 3. 拷贝构造函数
    std::string str4(str2);
    std::string str5 = str3;
    
    // 4. 从字符构造(重复 n 次)
    std::string str6(5, 'A');  // "AAAAA"
    
    // 5. 从子字符串构造
    std::string str7(str2, 6);      // 从位置 6 开始到末尾:"World"
    std::string str8(str2, 0, 5);   // 从位置 0 开始,长度 5:"Hello"
    
    // 6. C++11 初始化列表
    std::string str9{'H', 'e', 'l', 'l', 'o'};
    
    // 7. C++11 统一初始化
    std::string str10{"Modern C++"};
    
    std::cout << "str2: " << str2 << std::endl;
    std::cout << "str6: " << str6 << std::endl;
    std::cout << "str7: " << str7 << std::endl;
    std::cout << "str8: " << str8 << std::endl;
    
    return 0;
}

基本属性和容量

#include <iostream>
#include <string>
 
int main() {
    std::string str = "Hello World";
    
    // 长度和大小
    std::cout << "Length: " << str.length() << std::endl;    // 11
    std::cout << "Size: " << str.size() << std::endl;        // 11 (等价于 length)
    std::cout << "Capacity: " << str.capacity() << std::endl; // 实际分配的内存大小
    std::cout << "Max size: " << str.max_size() << std::endl; // 理论最大大小
    
    // 检查是否为空
    std::cout << "Is empty: " << std::boolalpha << str.empty() << std::endl;
    
    std::string emptyStr;
    std::cout << "Empty string is empty: " << emptyStr.empty() << std::endl;
    
    // 预分配内存
    str.reserve(100);  // 预分配至少 100 字符的空间
    std::cout << "After reserve(100), capacity: " << str.capacity() << std::endl;
    
    // 调整大小
    str.resize(5);     // 截断为 5 个字符:"Hello"
    std::cout << "After resize(5): '" << str << "'" << std::endl;
    
    str.resize(10, '*'); // 扩展到 10 个字符,用 '*' 填充:"Hello*****"
    std::cout << "After resize(10, '*'): '" << str << "'" << std::endl;
    
    // 清空字符串
    str.clear();
    std::cout << "After clear: '" << str << "', empty: " << str.empty() << std::endl;
    
    return 0;
}

字符串访问和修改

元素访问

#include <iostream>
#include <string>
 
int main() {
    std::string str = "Hello World";
    
    // 1. 下标运算符 [] - 不进行边界检查
    std::cout << "First character: " << str[0] << std::endl;
    std::cout << "Last character: " << str[str.length() - 1] << std::endl;
    
    // 修改字符
    str[0] = 'h';
    std::cout << "After modification: " << str << std::endl;
    
    // 2. at() 方法 - 进行边界检查,越界会抛出异常
    try {
        std::cout << "Character at index 6: " << str.at(6) << std::endl;
        // std::cout << str.at(100) << std::endl;  // 会抛出 std::out_of_range 异常
    } catch (const std::out_of_range& e) {
        std::cout << "Exception: " << e.what() << std::endl;
    }
    
    // 3. front() 和 back() - C++11
    std::cout << "Front: " << str.front() << std::endl;  // 第一个字符
    std::cout << "Back: " << str.back() << std::endl;    // 最后一个字符
    
    // 4. 获取 C 风格字符串
    const char* cstr = str.c_str();  // 返回以 null 结尾的 C 字符串
    std::cout << "C-style string: " << cstr << std::endl;
    
    const char* data_ptr = str.data();  // C++11 前不保证 null 结尾,C++11 后等价于 c_str()
    std::cout << "Data pointer: " << data_ptr << std::endl;
    
    // 5. 遍历字符串
    std::cout << "Characters: ";
    for (size_t i = 0; i < str.length(); ++i) {
        std::cout << str[i] << " ";
    }
    std::cout << std::endl;
    
    // 6. 范围 for 循环 (C++11)
    std::cout << "Range-based for: ";
    for (char c : str) {
        std::cout << c << " ";
    }
    std::cout << std::endl;
    
    // 7. 迭代器
    std::cout << "Using iterators: ";
    for (auto it = str.begin(); it != str.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

字符串赋值

#include <iostream>
#include <string>
 
int main() {
    std::string str;
    
    // 1. 赋值运算符
    str = "Hello";
    std::cout << "Assignment operator: " << str << std::endl;
    
    str = 'A';  // 单个字符赋值
    std::cout << "Single char assignment: " << str << std::endl;
    
    std::string other = "World";
    str = other;  // 字符串对象赋值
    std::cout << "String object assignment: " << str << std::endl;
    
    // 2. assign() 方法
    str.assign("New String");
    std::cout << "assign(): " << str << std::endl;
    
    str.assign(5, 'X');  // 5 个 'X'
    std::cout << "assign(5, 'X'): " << str << std::endl;
    
    str.assign(other, 1, 3);  // 从 other 的位置 1 开始,长度 3
    std::cout << "assign(other, 1, 3): " << str << std::endl;
    
    // 3. C++11 移动赋值
    std::string temp = "Temporary";
    str = std::move(temp);  // 移动赋值,temp 变为空
    std::cout << "Move assignment: " << str << std::endl;
    std::cout << "temp after move: '" << temp << "'" << std::endl;
    
    return 0;
}

字符串连接和追加

字符串连接

#include <iostream>
#include <string>
 
int main() {
    std::string str1 = "Hello";
    std::string str2 = "World";
    
    // 1. + 运算符
    std::string result1 = str1 + " " + str2;
    std::cout << "Using +: " << result1 << std::endl;
    
    std::string result2 = str1 + " C++";
    std::cout << "String + literal: " << result2 << std::endl;
    
    std::string result3 = "Welcome to " + str2;
    std::cout << "Literal + string: " << result3 << std::endl;
    
    // 2. += 运算符
    std::string str3 = "Hello";
    str3 += " ";
    str3 += str2;
    str3 += "!";
    std::cout << "Using +=: " << str3 << std::endl;
    
    // 3. append() 方法
    std::string str4 = "C++";
    str4.append(" is");
    str4.append(" awesome", 8);  // 只追加前 8 个字符
    str4.append(3, '!');         // 追加 3 个 '!' 字符
    std::cout << "Using append(): " << str4 << std::endl;
    
    // 4. 链式操作
    std::string str5;
    str5.append("Learning").append(" ").append("C++").append(" is fun!");
    std::cout << "Chain append: " << str5 << std::endl;
    
    // 5. 性能比较示例
    auto start = std::chrono::high_resolution_clock::now();
    
    // 低效方式:多次重新分配
    std::string inefficient;
    for (int i = 0; i < 10000; ++i) {
        inefficient += "a";
    }
    
    auto mid = std::chrono::high_resolution_clock::now();
    
    // 高效方式:预分配空间
    std::string efficient;
    efficient.reserve(10000);
    for (int i = 0; i < 10000; ++i) {
        efficient += "a";
    }
    
    auto end = std::chrono::high_resolution_clock::now();
    
    std::cout << "Inefficient time: " 
              << std::chrono::duration_cast<std::chrono::microseconds>(mid - start).count() 
              << " microseconds" << std::endl;
    std::cout << "Efficient time: " 
              << std::chrono::duration_cast<std::chrono::microseconds>(end - mid).count() 
              << " microseconds" << std::endl;
    
    return 0;
}

字符串查找和搜索

基本查找操作

#include <iostream>
#include <string>
 
int main() {
    std::string text = "Hello World, Hello C++, Hello Programming";
    
    // 1. find() - 查找子字符串
    size_t pos = text.find("Hello");
    if (pos != std::string::npos) {
        std::cout << "First 'Hello' found at position: " << pos << std::endl;
    }
    
    // 从指定位置开始查找
    pos = text.find("Hello", 1);  // 从位置 1 开始查找
    std::cout << "Second 'Hello' found at position: " << pos << std::endl;
    
    // 查找字符
    pos = text.find('W');
    std::cout << "'W' found at position: " << pos << std::endl;
    
    // 2. rfind() - 反向查找
    pos = text.rfind("Hello");
    std::cout << "Last 'Hello' found at position: " << pos << std::endl;
    
    // 3. find_first_of() - 查找任意指定字符中的第一个
    pos = text.find_first_of("aeiou");  // 查找第一个元音字母
    if (pos != std::string::npos) {
        std::cout << "First vowel '" << text[pos] << "' at position: " << pos << std::endl;
    }
    
    // 4. find_last_of() - 查找任意指定字符中的最后一个
    pos = text.find_last_of("aeiou");
    if (pos != std::string::npos) {
        std::cout << "Last vowel '" << text[pos] << "' at position: " << pos << std::endl;
    }
    
    // 5. find_first_not_of() - 查找第一个不在指定字符集中的字符
    pos = text.find_first_not_of("Hello ");
    if (pos != std::string::npos) {
        std::cout << "First non-'Hello ' char '" << text[pos] << "' at position: " << pos << std::endl;
    }
    
    // 6. find_last_not_of() - 查找最后一个不在指定字符集中的字符
    pos = text.find_last_not_of("gramming");
    if (pos != std::string::npos) {
        std::cout << "Last non-'gramming' char '" << text[pos] << "' at position: " << pos << std::endl;
    }
    
    // 7. 查找所有匹配项
    std::cout << "\nAll occurrences of 'Hello':" << std::endl;
    pos = 0;
    while ((pos = text.find("Hello", pos)) != std::string::npos) {
        std::cout << "Found at position: " << pos << std::endl;
        pos += 5;  // 移动到下一个可能的位置
    }
    
    return 0;
}

高级查找示例

#include <iostream>
#include <string>
#include <vector>
 
// 查找所有匹配的子字符串
std::vector<size_t> findAll(const std::string& text, const std::string& pattern) {
    std::vector<size_t> positions;
    size_t pos = 0;
    
    while ((pos = text.find(pattern, pos)) != std::string::npos) {
        positions.push_back(pos);
        pos += pattern.length();
    }
    
    return positions;
}
 
// 统计子字符串出现次数
int countOccurrences(const std::string& text, const std::string& pattern) {
    int count = 0;
    size_t pos = 0;
    
    while ((pos = text.find(pattern, pos)) != std::string::npos) {
        ++count;
        pos += pattern.length();
    }
    
    return count;
}
 
// 检查字符串是否包含指定模式
bool contains(const std::string& text, const std::string& pattern) {
    return text.find(pattern) != std::string::npos;
}
 
int main() {
    std::string document = "The quick brown fox jumps over the lazy dog.