C++—— String 类详解

String 类详解

2.1 std::string 类的引入和优势

std::string 类是 C++ 标准库中用于处理字符串的类。相比于 C 风格的字符数组,std::string 提供了以下优势:

  • 自动内存管理: 无需手动分配和释放内存,避免了内存泄漏和缓冲区溢出的风险。
  • 动态大小: 字符串的长度可以根据需要动态增长。
  • 丰富的成员函数: 提供了各种方便的字符串操作函数。
  • 更安全易用: 避免了 C 风格字符串操作中常见的错误。

2.2 std::string 类的常用构造函数

cpp 复制代码
#include <string>
#include <iostream>

int main() {
  std::string s1;                      // 默认构造函数,创建一个空字符串
  std::string s2("Hello");             // 使用 C 风格字符串初始化
  std::string s3 = "World";            // 拷贝初始化
  std::string s4(s2);                  // 拷贝构造函数
  std::string s5(s2, 1, 3);            // 使用 s2 的子串初始化 (从索引 1 开始,长度为 3)
  std::string s6(10, 'a');             // 创建包含 10 个 'a' 的字符串
  std::string s7(s2.begin(), s2.end()); // 使用迭代器初始化

  std::cout << "s1: " << s1 << std::endl;
  std::cout << "s2: " << s2 << std::endl;
  std::cout << "s3: " << s3 << std::endl;
  std::cout << "s4: " << s4 << std::endl;
  std::cout << "s5: " << s5 << std::endl;
  std::cout << "s6: " << s6 << std::endl;
  std::cout << "s7: " << s7 << std::endl;

  return 0;
}

2.3 std::string 类的常用操作函数

函数 描述 示例
+ (连接) 连接两个字符串或字符串与字符/C 风格字符串 std::string s = "Hello" + " " + "World";
+= (追加) 将字符串或字符/C 风格字符串追加到现有字符串末尾 std::string s = "Hello"; s += " World!";
append 在字符串末尾追加字符串或其子串 std::string s = "Hello"; s.append(" World");
find 查找子串第一次出现的位置,找不到返回 std::string::npos std::string s = "abcdefg"; size_t pos = s.find("cde");
rfind 查找子串最后一次出现的位置 std::string s = "abcdecdef"; size_t pos = s.rfind("cde");
find_first_of 查找字符串中第一个与指定字符集合中任何字符匹配的字符的位置 std::string s = "abcdefg"; size_t pos = s.find_first_of("ce");
substr 返回指定范围的子串 std::string s = "abcdefg"; std::string sub = s.substr(1, 3);
insert 在指定位置插入字符串或字符 std::string s = "abc"; s.insert(1, "xyz");
replace 替换指定范围内的子串 std::string s = "abcdefg"; s.replace(1, 3, "XYZ");
erase 删除指定位置或范围内的字符 std::string s = "abcdefg"; s.erase(1, 3);
length / size 返回字符串的长度 (字符个数) std::string s = "Hello"; int len = s.length();
capacity 返回当前已分配的存储空间大小 (可能大于实际长度) std::string s = "Hello"; int cap = s.capacity();
empty 检查字符串是否为空 std::string s; bool isEmpty = s.empty();
clear 清空字符串内容,使其长度变为 0 std::string s = "Hello"; s.clear();
compare 比较两个字符串 std::string s1 = "abc"; std::string s2 = "abd"; int res = s1.compare(s2);
c_str 返回一个指向以 null 结尾的 C 风格字符串的常量指针 (const char*) std::string s = "Hello"; const char* cstr = s.c_str();
示例:字符串的操作
cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

int main() {
  string str = "Hello";
  string world = " World";

  // 连接字符串
  string greeting = str + world;
  cout << "Greeting: " << greeting << endl; // 输出:Hello World

  // 追加字符串
  greeting += "!";
  cout << "Greeting: " << greeting << endl; // 输出:Hello World!

  // 查找子串
  size_t pos = greeting.find("World");
  if (pos != string::npos) {
    cout << "'World' found at position: " << pos << endl; // 输出:'World' found at position: 6
  }

  // 截取子串
  string sub = greeting.substr(0, 5);
  cout << "Substring: " << sub << endl; // 输出:Hello

  // 替换子串
  greeting.replace(6, 5, "Universe");
  cout << "Greeting after replace: " << greeting << endl; // 输出:Hello Universe!

  return 0;
}

2.4 访问字符串元素

与 C 风格字符串类似,std::string 允许通过下标访问单个字符,并提供了更安全的 at() 方法。

方法 描述 示例
[] 通过下标访问字符串元素,不进行越界检查,可能导致未定义行为 char c = str[0];
at() 通过下标访问字符串元素,进行越界检查 ,越界会抛出 std::out_of_range 异常 char c = str.at(0);
front() 返回字符串的第一个字符的引用 char c = str.front();
back() 返回字符串的最后一个字符的引用 char c = str.back();

示例:访问字符串元素

cpp 复制代码
#include <iostream>
#include <string>
#include <stdexcept> // 需要包含这个头文件来处理异常

using namespace std;

int main() {
  string str = "Hello";

  cout << "First character: " << str[0] << endl;       // 输出:H
  cout << "First character: " << str.at(0) << endl;     // 输出:H
  cout << "Last character: " << str.back() << endl;      // 输出:o

  try {
    // str.at(10); // 这会抛出 std::out_of_range 异常
  } catch (const out_of_range& e) {
    cerr << "Caught an out_of_range exception: " << e.what() << endl;
  }

  return 0;
}

2.5 std::string 的迭代器

std::string 也支持迭代器,可以用于遍历字符串中的字符。

  • begin(): 返回指向字符串第一个字符的迭代器。
  • end(): 返回指向字符串末尾之后一个位置的迭代器。
  • rbegin(): 返回指向字符串最后一个字符的反向迭代器。
  • rend(): 返回指向字符串开头之前一个位置的反向迭代器。

示例:使用迭代器遍历字符串

cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

int main() {
  string str = "Hello";

  cout << "Using forward iterators: ";
  for (string::iterator it = str.begin(); it != str.end(); ++it) {
    cout << *it << " "; // 输出:H e l l o
  }
  cout << endl;

  cout << "Using reverse iterators: ";
  for (string::reverse_iterator rit = str.rbegin(); rit != str.rend(); ++rit) {
    cout << *rit << " "; // 输出:o l l e H
  }
  cout << endl;

  // C++11 引入的基于范围的 for 循环更加简洁
  cout << "Using range-based for loop: ";
  for (char c : str) {
    cout << c << " "; // 输出:H e l l o
  }
  cout << endl;

  return 0;
}

2.6 std::string 的内存管理

std::string 负责管理其内部存储字符串数据的内存。当你对 std::string 对象进行操作(如追加、插入等)时,如果当前的内存空间不足以容纳新的字符串,std::string 会自动分配更大的内存空间,并将原有数据复制到新的空间。 这就是为什么使用 std::string 可以避免手动内存管理带来的问题。


相关推荐
稻草猫.9 小时前
Java多线程(一)
java·后端·java-ee·idea
Java中文社群10 小时前
炸裂:SpringAI新版发布,终于支持断线重连了!
java·后端·ai编程
哈喽姥爷10 小时前
Spring Boot--Bean的扫描和注册
java·spring boot·后端·bean的扫描和注册
problc10 小时前
Spring Boot `@Service` 互相调用全攻略:`@Autowired` vs `@Resource`
java·spring boot·后端
文心快码BaiduComate10 小时前
文心快码3.5S全新升级,体验多智能体协同开发,最高赢无人机!
前端·后端·程序员
就是帅我不改11 小时前
10万QPS压垮系统?老司机一招线程池优化,让性能飞起来!
后端·面试·github
uzong11 小时前
系统稳定性保障:研发规约V1.0
后端
Ray6611 小时前
log4j2.xml配置文件详解
后端
Frank_zhou11 小时前
Easy-Es 架构设计详解
后端·elasticsearch
狗头大军之江苏分军11 小时前
Meta万人裁员亲历者自述:小扎尝到了降本的甜头
前端·后端·github