前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >C++中string常用方法总结

C++中string常用方法总结

作者头像
用户11029137
发布2025-03-16 20:46:50
发布2025-03-16 20:46:50
4900
代码可运行
举报
文章被收录于专栏:编程学习编程学习
运行总次数:0
代码可运行

📝前言: STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。今天就让我们先学习STL中的重要容器之一——string(文中表粗为重要用法)

一,了解STL

STL 最初由 Alexander Stepanov 等人开发,后被纳入 C++ 标准。STL 有标准规范,但是,不同公司为了提高性能,或者其他原因,在实现 STL 时,在底层数据结构和算法的选择上可能会有差异。比如,Visual C++ 编译器中自带的 STL 实现和GCC 编译器中的 STL 实现就有所差异。

  • STL主要由以下六个部分组成:

在学习STL的时候,更多是一个探索过程,我们要多查文档了解用法,在实践和练习中学习。https://legacy.cplusplus.com/reference/这个文档按头文件整理,虽然不是官方的,但是对初学者较为友好。

二,string常用接口

在 C++ 里,std::string 是标准库中的类,它处于 std 命名空间中。 首先介绍一下string和C风格字符串的区别:

代码语言:javascript
代码运行次数:0
运行
复制
	string s1("hello world");
	char s2[] = "hello world";

对于上面两个字符串在内存中的存储,s1不带\0s2\0

所以对于C风格的字符串,我们无法直接使用string的方法,对于string类型的字符串,我们要使用C风格字符串的方法需要通过c_str()转换成C风格的字符串,因为C风格的字符串操作大多是需要使用\0的。

1. 构造函数

  • string(): 默认构造函数,创建一个空字符串。
  • string(const char* s): 用 C 风格字符串初始化。
  • string(const string& str): 拷贝构造函数。
  • string(size_t n, char c): 创建一个包含 n 个字符 c 的字符串。

示例:

代码语言:javascript
代码运行次数:0
运行
复制
    std::string s1; // 空的string类对象

    // 使用 C 风格字符串初始化
    std::string s2("Hello, World!");

    // 使用拷贝构造函数,用 s2 初始化 s3
    std::string s3(s2);

    // 创建一个包含 5 个字符 'A' 的字符串
    std::string s4(5, 'A');

2. 赋值操作

  • string& operator=(const string& str): 赋值操作符。
代码语言:javascript
代码运行次数:0
运行
复制
    std::string str1 = "Initial value"; // 这是拷贝构造初始化
    std::string str2;
    // 使用赋值操作符 = 将 str1 的内容赋给 str2
    str2 = str1;

3. 元素访问及遍历

  • char& operator[](size_t pos): 访问指定位置的字符(不检查边界)。就和使用数组下标一样。
代码语言:javascript
代码运行次数:0
运行
复制
    std::string str = "Hello, World!";
    // 使用 operator[] 访问指定位置的字符(不检查边界)
    // 修改指定位置的字符
    str[0] = 'h';

==迭代器==是学习容器非常重要的一个概念,迭代器类似指针,也可以加减来移动,但是不能大小比较,且不同类型的迭代器不能比较(如iteratorreverse_iterator类型不能比较)

  • iterator begin(): 返回指向字符串开头的迭代器。
  • iterator end(): 返回指向字符串末尾的迭代器。
  • reverse_iterator rbegin(): 返回指向字符串末尾的反向迭代器。
  • reverse_iterator rend(): 返回指向字符串开头的反向迭代器。

利用迭代器访问:

代码语言:javascript
代码运行次数:0
运行
复制
int main() {
    std::string str = "Hello, World!";

    // 使用 begin() 和 end() 正向遍历字符串
    std::cout << "正向遍历字符串: ";
    for (std::string::iterator it = str.begin(); it != str.end(); ++it) {
        std::cout << *it;
    }
    std::cout << std::endl;

    // 使用 rbegin() 和 rend() 反向遍历字符串
    std::cout << "反向遍历字符串: ";
    for (std::string::reverse_iterator rit = str.rbegin(); rit != str.rend(); ++rit) {
        std::cout << *rit;
    }
    std::cout << std::endl;
	return 0;
}

输出:

代码语言:javascript
代码运行次数:0
运行
复制
正向遍历字符串: Hello, World!
反向遍历字符串: !dlroW ,olleH

auto用于自动推到类型,常用在替换较长的代码名称。 注意:auto 声明的变量必须有初始值,因为编译器需要根据初始值来推导类型。且auto不能用在函数参数 利用auto和范围for访问:

代码语言:javascript
代码运行次数:0
运行
复制
    // 使用范围 for 和 auto 访问
    for (auto ch : str) {
        std::cout << ch;
    }
    return 0;
}

4. 大小和容量操作

  • size_t size() const: 返回字符串的长度。
  • size_t length() const: 与 size() 相同,返回字符串的长度。
  • bool empty() const: 判断字符串是否为空。
  • void resize(size_t n): 调整字符串的大小。
  • size_t capacity() const: 返回当前分配的存储空间大小。
  • void reserve(size_t n): 预留存储空间。
  • void clear(): 清空字符串。(但是开的空间不清)
代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <string>

int main() {
    // 定义一个字符串对象并初始化为 "Hello"
    std::string str = "Hello";

    // 使用 size() 方法返回字符串的长度
    // 这里输出字符串使用 size() 方法得到的长度
    std::cout << "使用 size() 方法得到的字符串长度: " << str.size() << std::endl;

    // 使用 length() 方法返回字符串的长度
    // length() 和 size() 功能一样,这里输出使用 length() 方法得到的长度
    std::cout << "使用 length() 方法得到的字符串长度: " << str.length() << std::endl;

    // 使用 empty() 方法判断字符串是否为空
    // 根据 empty() 的返回结果输出字符串是否为空的信息
    std::cout << "字符串是否为空? " << (str.empty() ? "是" : "否") << std::endl;

    // 使用 resize() 方法调整字符串的大小
    // 将字符串大小调整为 10,如果新长度大于原长度,用 '!' 填充,如果新长度小于原长度,则截断
    str.resize(10, '!');
    // 输出调整大小后的字符串
    std::cout << "调整大小为 10 并用 '!' 填充后的字符串: " << str << std::endl;
    // 输出调整大小后字符串的新长度
    std::cout << "调整大小后的新长度: " << str.size() << std::endl;

    // 使用 capacity() 方法返回当前为字符串分配的存储空间大小
    std::cout << "当前字符串分配的存储空间大小: " << str.capacity() << std::endl;

    // 使用 reserve() 方法预留存储空间
    // 预留至少能容纳 20 个字符的存储空间
    str.reserve(20);
    // 输出预留存储空间后的容量
    std::cout << "预留 20 个字符存储空间后的容量: " << str.capacity() << std::endl;

    // 使用 clear() 方法清空字符串
    str.clear();
    // 再次使用 empty() 方法判断字符串是否为空并输出结果
    std::cout << "清空字符串后是否为空? " << (str.empty() ? "是" : "否") << std::endl;

    return 0;
}

运行结果:

说明:为什么预留reserve(20)但是开的capacity31? 首先,先了解一下string的自动扩容: 当向string 中添加字符,使得字符数量超过其当前分配的容量capacity 时,string会自动进行扩容操作。但是,不同的标准库实现可能采用不同的扩容策略,但常见的做法是按照一定的倍数进行扩容。例如,当需要扩容时,可能会将容量扩大为原来的2 倍,这样可以减少频繁扩容带来的性能开销。 所以当我们reserve(20)的时候,编译器会根据自己的标准进行扩容,确保开的空间是>=20的。 对于reserve(n),如果n比目前的字符串小,就不会执行,但是如果比capacity小,比字符串大则可能执行,由编译器决定.

5. 修改操作

  • string& append(const string& str): 在字符串末尾追加字符串。
  • string& operator+=(const string& str): 追加字符串。
  • void push_back(char c): 在字符串末尾追加一个字符。
  • string& insert(size_t pos, const string& str): 在指定位置插入字符串。
  • string& erase(size_t pos = 0, size_t len = npos): 删除从 pos 开始的 len 个字符。
  • string& replace(size_t pos, size_t len, const string& str): 替换从 pos 开始的 len 个字符为 str

示例:

代码语言:javascript
代码运行次数:0
运行
复制
int main() 
{
    std::string str = "Hello";

    // 使用 append(const string& str) 在字符串末尾追加字符串
    std::string appendStr = ", World";
    str.append(appendStr);
    std::cout << "使用 append 追加后: " << str << std::endl;

    // 使用 operator+=(const string& str) 追加字符串
    std::string anotherAppend = "!";
    str += anotherAppend;
    std::cout << "使用 += 追加后: " << str << std::endl;

    // 使用 push_back(char c) 在字符串末尾追加一个字符
    str.push_back('?');
    std::cout << "使用 push_back 追加字符后: " << str << std::endl;

    // 使用 insert(size_t pos, const string& str) 在指定位置插入字符串
    std::string insertStr = " amazing";
    str.insert(5, insertStr);
    std::cout << "在位置 5 插入字符串后: " << str << std::endl;

    // 使用 erase(size_t pos = 0, size_t len = npos) 删除从 pos 开始的 len 个字符
    str.erase(5, insertStr.length());
    std::cout << "删除插入的字符串后: " << str << std::endl;

    // 使用 replace(size_t pos, size_t len, const string& str) 替换从 pos 开始的 len 个字符为 str
    std::string replaceStr = "Hi";
    str.replace(0, 5, replaceStr);
    std::cout << "替换前 5 个字符后: " << str << std::endl;

    return 0;
}

运行结果:

6. 子字符串操作

  • string substr(size_t pos = 0, size_t len = npos) const: 返回从 pos 开始的 len 个字符组成的子字符串。

示例:

代码语言:javascript
代码运行次数:0
运行
复制
    std::string mainStr = "Hello, Hello, World!";
    std::string Sub = mainStr.substr(3, 7);
    std::cout << Sub << std::endl; // 输出:lo, Hel

7. 查找操作

  • size_t find(const string& str, size_t pos = 0) const: 从 pos 开始查找子字符串 str
  • size_t rfind(const string& str, size_t pos = npos) const: 从 pos 开始反向查找子字符串 str

nposstatic const size_t 类型的-1,但是size_t 是一种无符号整数类型,所以以补码的形式存储-1就相当于一个很大的数

示例:

代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <string>

int main() {
    std::string mainStr = "Hello, Hello, World!";
    std::string subStr = "Hello";

    // 使用 find(const string& str, size_t pos = 0) 从 pos 开始查找子字符串 str
    size_t foundPos = mainStr.find(subStr, 0);
    if (foundPos != std::string::npos) {
        std::cout << "使用 find 从位置 0 开始查找,首次找到 \"" << subStr << "\" 的位置是: " << foundPos << std::endl;
    }
    else {
        std::cout << "使用 find 从位置 0 开始查找,未找到 \"" << subStr << "\"。" << std::endl;
    }

    // 从位置 7 开始查找
    foundPos = mainStr.find(subStr, 7);
    if (foundPos != std::string::npos) {
        std::cout << "使用 find 从位置 7 开始查找,找到 \"" << subStr << "\" 的位置是: " << foundPos << std::endl;
    }
    else {
        std::cout << "使用 find 从位置 7 开始查找,未找到 \"" << subStr << "\"。" << std::endl;
    }

    // 使用 rfind(const string& str, size_t pos = npos) 从 pos 开始反向查找子字符串 str
    size_t rfoundPos = mainStr.rfind(subStr);
    if (rfoundPos != std::string::npos) {
        std::cout << "使用 rfind 反向查找,最后一次找到 \"" << subStr << "\" 的位置是: " << rfoundPos << std::endl;
    }
    else {
        std::cout << "使用 rfind 反向查找,未找到 \"" << subStr << "\"。" << std::endl;
    }

    return 0;
}

运行结果:

8. 比较操作

  • bool operator==(const string& str) const: 判断两个字符串是否相等。
  • bool operator!=(const string& str) const: 判断两个字符串是否不相等。
  • int compare(const string& str) const: 比较两个字符串

C ++字符串支持常见的比较操作符(>,>=,<,<=,==,!=),甚至支持string与C-string的比较(如 str<”hello”)。 因为会发生隐式类型转换,把C风格的转换成string

示例: compare 方法提供了更多的重载形式,支持用索引值和长度定位子串来进行比较,功能灵活

代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <string>

int main() {
    std::string str1 = "apple pie";
    std::string str2 = "applesauce";

    // 比较 str1 从位置 0 开始的 5 个字符和 str2 从位置 0 开始的 5 个字符
    int result = str1.compare(0, 5, str2, 0, 5);
    if (result == 0) {
        std::cout << "str1 和 str2 的前 5 个字符相等" << std::endl;
    }

    return 0;
}

10. C 风格字符串转换

  • const char* c_str() const: 返回一个指向 C 风格字符串的指针。

示例:

代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <string>
#include <cstring>

int main() {
    std::string str1 = "apple";
    std::string str2 = "banana";

    // 使用 c_str() 转换为 C 风格字符串
    const char* cstr1 = str1.c_str();
    const char* cstr2 = str2.c_str();

    // 使用 C 风格的 strcmp 函数比较两个字符串
    int result = strcmp(cstr1, cstr2);
    if (result < 0) {
        std::cout << "str1 小于 str2" << std::endl;
    }
    else if (result > 0) {
        std::cout << "str1 大于 str2" << std::endl;
    }
    else {
        std::cout << "str1 等于 str2" << std::endl;
    }

    return 0;
}

11. getline

getline用于从输入流(标准或文件)中读取一行文本(默认以\n作为分隔符) scanfcin默认是以空白字符(空格、制表符、换行符等)作为分隔来读取数据的。 函数原型: std::istream& getline(std::istream& is, std::string& str, char delim);

  • is:输入流对象,通常是 std::cin 用于从标准输入读取数据。
  • str:用于存储读取到的一行文本的 std::string 对象。
  • delim(可选):分隔符,默认是换行符 \n。当遇到该分隔符时,读取停止(不会读取分隔符)。

示例:

代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <string>

int main() {
    std::string line;
    std::cout << "请输入一行文本:";
    // 使用默认分隔符(换行符)读取一行
    std::getline(std::cin, line);
    std::cout << "你输入的文本是:" << line << std::endl;

    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一,了解STL
  • 二,string常用接口
    • 1. 构造函数
    • 2. 赋值操作
    • 3. 元素访问及遍历
    • 4. 大小和容量操作
    • 5. 修改操作
    • 6. 子字符串操作
    • 7. 查找操作
    • 8. 比较操作
    • 10. C 风格字符串转换
    • 11. getline
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档