基本定义与初始化

  • 定义string类定义在<string>头文件中,使用时需要包含该头文件。它是一个模板类,实际上是basic_string<char>的别名。
  • 初始化:可以通过多种方式进行初始化,例如:
  • string s1;:默认初始化,创建一个空字符串。
  • string s2 = "Hello";:使用字符串字面值初始化。
  • string s3(s2);:使用已有的字符串对象进行复制初始化。
  • string s4(5, 'a');:创建一个包含 5 个字符'a'的字符串。

基本操作

  • 获取字符串长度:使用length()size()成员函数,例如string s = "Hello"; int len = s.length();,这两个函数的功能相同,都返回字符串中字符的个数。
  • 访问字符:可以使用[]运算符或at()成员函数来访问字符串中的单个字符。例如string s = "Hello"; char c1 = s[0]; char c2 = s.at(1);,但使用at()函数在越界访问时会抛出异常,而[]运算符越界访问行为是未定义的。
  • 修改字符:可以通过[]运算符或at()函数对字符串中的字符进行修改,例如string s = "Hello"; s[0] = 'h'; s.at(1) = 'e';

字符串拼接与连接

  • 使用+运算符:可以将两个字符串对象或一个字符串对象与一个字符串字面值拼接在一起,例如string s1 = "Hello"; string s2 = "World"; string s3 = s1 + " " + s2;
  • 使用append()函数:该函数可以在字符串末尾添加另一个字符串、字符串的一部分或指定数量的字符,例如string s1 = "Hello"; string s2 = "World"; s1.append(s2);

字符串比较

  • 使用比较运算符:可以使用==!=<><=>=等比较运算符对字符串进行比较。比较是按照字典序进行的,即逐个字符比较它们的 ASCII 码值。
  • 使用compare()函数:该函数提供了更灵活的比较方式,可以指定比较的范围等,例如string s1 = "Hello"; string s2 = "Hello"; int result = s1.compare(s2);,如果两个字符串相等,result为 0。

子字符串操作

  • 获取子字符串:使用substr()成员函数可以获取字符串的子字符串,它接受两个参数,第一个参数是子字符串的起始位置,第二个参数是子字符串的长度。例如string s = "HelloWorld"; string sub = s.substr(0, 5);

查找与替换

  • 查找字符或子字符串:使用find()函数可以在字符串中查找指定的字符或子字符串,返回第一次出现的位置,如果未找到则返回string::npos。例如string s = "HelloWorld"; int pos = s.find('o');
  • 替换字符或子字符串:使用replace()函数可以将字符串中的指定字符或子字符串替换为其他字符或子字符串,例如string s = "HelloWorld"; s.replace(0, 5, "Hi");

输入与输出

  • 输入:可以使用cin来读取用户输入的字符串,例如string s; cin >> s;,但这种方式会以空格或换行符作为分隔符,读取到第一个空格或换行符之前的内容。如果要读取一行包含空格的字符串,可以使用getline(cin, s);
  • 输出:可以使用cout来输出字符串,例如string s = "Hello"; cout << s << endl;

1. size() 与 length()

功能:两者都用于返回字符串的长度,即字符串中字符的数量。

示例代码

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";
    std::cout << "使用 size() 函数:" << str.size() << std::endl;
    std::cout << "使用 length() 函数:" << str.length() << std::endl;
    return 0;
}

区别:在 string 类中,size() 和 length() 函数的功能完全相同,可互换使用。它们的存在主要是为了兼容不同的容器类型,因为其他容器类(如 vector 等)使用 size() 函数,而一些旧代码习惯使用 length() 函数。

2. substr() 与 substring()

功能:都用于提取子字符串。

示例代码

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";
    std::string sub1 = str.substr(7); // 从第 7 个字符开始提取到结尾
    std::string sub2 = str.substr(7, 5); // 从第 7 个字符开始提取 5 个字符

    std::cout << "使用 substr() 函数:" << sub1 << std::endl;
    std::cout << "使用 substr() 函数:" << sub2 << std::endl;

    return 0;
}

区别string 类中没有 substring() 函数。substr() 函数是唯一的,它接受一个或两个参数。第一个参数是起始位置,第二个参数(可选)是要提取的字符数量。如果省略第二个参数,将提取从起始位置到字符串末尾的所有字符。

3. find() 与 rfind()

功能:都用于查找子字符串或字符在字符串中的位置。

示例代码

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";
    size_t pos1 = str.find("World"); // 从前往后找
    size_t pos2 = str.rfind("o");    // 从后往前找

    std::cout << "使用 find() 函数:" << pos1 << std::endl;
    std::cout << "使用 rfind() 函数:" << pos2 << std::endl;

    return 0;
}

区别

  • find() 函数从字符串的开头开始查找,返回第一个匹配的子字符串或字符的位置,如果未找到则返回 string::npos
  • rfind() 函数从字符串的末尾开始查找,返回最后一个匹配的子字符串或字符的位置,如果未找到则返回 string::npos

4. erase() 与 clear()

功能:都用于删除字符串中的字符。

示例代码

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";
    str.erase(5); // 删除从第 5 个字符开始到结尾的所有字符
    std::cout << "使用 erase() 函数:" << str << std::endl;

    str = "Hello, World!";
    str.clear(); // 清除整个字符串
    std::cout << "使用 clear() 函数:" << str << std::endl;

    return 0;
}

区别

  • erase() 函数可以根据参数的不同,删除字符串中的部分字符或一段字符。可以接受一个起始位置和长度作为参数,如 str.erase(start_index, length),或者只接受一个起始位置,表示从该位置删除到字符串末尾。
  • clear() 函数则是清除整个字符串,使其长度为 0。

5. insert() 与 append()

功能:都用于向字符串中添加字符或子字符串。

示例代码

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello";
    str.insert(5, ", World"); // 在第 5 个位置插入 ", World"
    std::cout << "使用 insert() 函数:" << str << std::endl;

    str = "Hello";
    str.append(", World"); // 在末尾添加 ", World"
    std::cout << "使用 append() 函数:" << str << std::endl;

    return 0;
}

区别

  • insert() 函数可以在字符串的任意位置插入字符或子字符串,它可以接受插入的位置和要插入的内容作为参数,还可以接受迭代器和迭代器范围作为参数。
  • append() 函数专门用于在字符串的末尾添加字符或子字符串,可以接受字符串、字符数组、单个字符等,主要用于字符串的拼接操作。

6. replace() 与 assign()

功能:都用于修改字符串的部分内容。

示例代码

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";
    str.replace(7, 5, "C++"); // 从第 7 个位置开始,替换 5 个字符为 "C++"
    std::cout << "使用 replace() 函数:" << str << std::endl;

    str = "Hello, World!";
    str.assign("C++"); // 用 "C++" 替换整个字符串
    std::cout << "使用 assign() 函数:" << str << std::endl;

    return 0;
}

区别

  • replace() 函数可以替换字符串中指定位置和长度的部分内容,也可以替换某个范围的内容,有多种重载形式。
  • assign() 函数主要用于将整个字符串替换为新的内容,可以是另一个字符串、字符数组、字符序列等。

7. at() 与 operator[]

功能:都用于访问字符串中指定位置的字符。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";
    char c1 = str.at(7);
    char c2 = str[7];

    std::cout << "使用 at() 函数:" << c1 << std::endl;
    std::cout << "使用 operator[] 函数:" << c2 << std::endl;

    return 0;
}

区别

  • at() 函数在访问越界时会抛出 std::out_of_range 异常,提供了边界检查。
  • operator[] 访问越界时会导致未定义行为,使用时要确保不越界。

8. c_str() 与 data()

功能:都用于将 string 转换为 C 风格的字符数组。

示例代码

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";
    const char* cstr1 = str.c_str();
    const char* cstr2 = str.data();

    std::cout << "使用 c_str() 函数:" << cstr1 << std::endl;
    std::cout << "使用 data() 函数:" << cstr2 << std::endl;

    return 0;
}

区别

  • c_str() 函数返回一个以 \0 结尾的 C 风格字符串,通常用于与 C 函数的接口兼容。
  • data() 函数返回一个指向字符串存储的字符数组的指针,但不保证字符串以 \0 结尾(不过在大多数实现中,结果与 c_str() 相同)。在 C++11 之后,data() 也保证以 \0 结尾,并且可以用于访问 string 的内部存储,但应谨慎使用。