C++ STL标准库 《string原理与实战分析》

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
Elasticsearch Serverless检索通用型,资源抵扣包 100CU*H
简介: C++ STL标准库 《string原理与实战分析》

一、string原理

std::string 是 STL 中的一个容器类,用于处理字符串数据。以下是 std::string 的一些基本原理:

  1. 动态数组std::string 内部通常使用动态数组(如 char 数组)来存储字符。这意味着 std::string 可以根据需要自动调整大小。
  2. 短字符串优化(SSO):为了提高小字符串的性能,std::string 实现了短字符串优化。这意味着对于短字符串,std::string 可能不会使用动态分配的内存,而是在对象的内部存储空间中直接存储字符。
  3. 内存管理std::string 负责管理其内部字符数组的内存。当字符串增长时,std::string 会进行内存重新分配,并复制旧字符到新分配的内存中。
  4. 迭代器std::string 支持迭代器,允许用户使用迭代器遍历字符串中的字符。
  5. 容量和大小std::string 提供了 .size() 方法来获取字符串的长度,以及 .capacity() 方法来获取当前分配的内存大小。
  6. 构造函数和析构函数std::string 有多种构造函数,允许从不同的数据源创建字符串,如 C 风格的字符数组、另一个 std::string 对象、字符等。析构函数负责释放 std::string 占用的内存。
  7. 成员函数std::string 提供了丰富的成员函数,如 append()insert()erase()find() 等,用于操作字符串。
  8. C++11 特性:从 C++11 开始,std::string 支持移动语义,这意味着在某些情况下,std::string 对象可以高效地在函数间传递,而不需要复制整个字符串。
  9. 异常安全std::string 的操作通常是异常安全的,这意味着即使在操作过程中发生异常,std::string 对象也会保持在有效状态。
  10. 本地化std::string 支持本地化功能,可以与本地化相关的函数(如 std::collate)一起使用,以支持多语言环境。


二、string实战操作分析

1、输入

string s;

cin >> s; 
getline(cin, s) ;       //使用默认的'\n'作为终止符
getline(cin, s, '!') ;    //以'!'作为终止符

2、复制

string s1 = "hello World" ;
string s2 = s1 ;        //"hello World"     复制,
string s3(s1);      //"hello World"      拷贝构造函数, 
string s4(s1, 2);    //"llo World"     将s1的第2个位置到末尾当作字符串的初值 
string s5(s1, 3, 5);    //"lo Wo"      将s1的第2个位置开始的5个字符作为字符串的初值 
string s8(5, 'a');   //“aaaaa”     生成一个字符串,包含5个c字符

3、连接

string s1 = "Hello" ;
string s2 = "World" ;string s3, s4;
s1 += s2 ;          //"HelloWorld"    连接  
s3 = string("aaa") + "bbb";    //"aaabbb" 
s4 = "aaa" + "bbb";    //错误, 必须转成string类型!!!!!

4、比较

string s1 = "hello" ;
string s2 = "world" ;
if(s1 < s2)
cout<<"s1 < s2" ;    //比较

5、倒置串

string s = "hello" ;
reverse(s.begin(), s.end()) ;        //需要包含algorithm头文件, #include<algorithm> 

6、查找串

string s1 = "hhhelloworlddd" ;   //位置从0 ~ 9 
s1.find("w") ;    // 7    找第1个w的位置 
s1.find("w", 10) ;    // -1     从第10个位置开始找w  

s1.find_first_of("o");   //6     找第1次出现"o"的位置 
s1.find_first_of("o",7);  //8    从s1的第7个位置开始查找 
s1.find_first_not_of("h");  //3    找第1个不是"h"的字符的位置 

s1.find_last_of("o");  //8     //从后面开始找"o" 
s1.find_last_of("o", 7);  //6   //从后面7个字符中找"o"出现的位置 
s1.find_last_not_of("d");  //10

7、替换和字串

string s1,s2,s3; 
s1 = "hello world!" ;   
s2 = s1.substr(3, 5);  //"lo wo"    从第3个位置开始,往后5个字符 
s3 = s1.substr(6);    //"world!"    从第6个字符到末尾部分 
s1.replace(2, 5, "tt");  //"hettorld"    从第2个位置,往后5个字符换成“tt”

8、修改字符串

①. append - 追加
 string s = "hello" ;
 s.append("world") ;        //将"world"追加到s中
    
②. push_back - 追加字符到字符串
 string s = "hello" ;
 s.push_back('!') ;        //将'!'追加字符到字符串s中
    
③. insert - 插入
 string s = "hello" ;
 s.insert(2, "www") ;    //将字符串"www"插入到字符串s中, 插入位置为2
            
④. erase - 从字符串中擦除一些字符
 string s = "hello" ;
 s.erase(1, 2) ;            //从下标为1处向后擦去2个字符
            
⑤. swap - 与另一字符串交换内容
 string s1 = "hello" ;
 string s2 = "world" ;
 s1.swap(s2) ;            //将s1与s2中的字符串进行交换

9、获取字符串状态

 s.size()                //返回字符串大小
 s.length()              //返回字符串长度
 s.max_size()            //返回字符串最大长度
 s.clear()               //清空字符串
 s.empty()               //判断字符串是否为空


10、string中的所有s1都替换成s2

#include <iostream>
#include <string>

using namespace std;

//"12212"这个字符串的所有"12"都替换成"21"
string& replace_all(string str, const string& old_value, const string& new_value)  //替换为22211
{
    while (true)
    {
        string::size_type pos(0);
        if ((pos = str.find(old_value)) != string::npos)
        {
            str.replace(pos, old_value.length(), new_value);
        }
        else
        {
            break;
        }
    }
    return str;
}

string& replace_all_distinct(string str, const string& old_value, const string& new_value) //替换为21221
{
    for (string::size_type pos(0); pos != string::npos; pos += new_value.length())
    {
        if ((pos = str.find(old_value, pos)) != string::npos)
        {
            str.replace(pos, old_value.length(), new_value);
        }
        else
        {
            break;
        }
    }
    return str;
}

int main()
{
    cout << replace_all(string("12212"), "12", "21") << endl;   //22211
    cout << replace_all_distinct(string("12212"), "12", "21") << endl;   //21221

    return 0;
}


相关文章
|
7月前
|
算法 C++ 容器
C++标准库(速查)总结
C++标准库(速查)总结
165 6
|
7月前
|
存储 算法 C++
C++ STL 初探:打开标准模板库的大门
C++ STL 初探:打开标准模板库的大门
175 10
|
7月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
149 3
|
3月前
|
安全 C语言 C++
彻底摘明白 C++ 的动态内存分配原理
大家好,我是V哥。C++的动态内存分配允许程序在运行时请求和释放内存,主要通过`new`/`delete`(用于对象)及`malloc`/`calloc`/`realloc`/`free`(继承自C语言)实现。`new`分配并初始化对象内存,`delete`释放并调用析构函数;而`malloc`等函数仅处理裸内存,不涉及构造与析构。掌握这些可有效管理内存,避免泄漏和悬空指针问题。智能指针如`std::unique_ptr`和`std::shared_ptr`能自动管理内存,确保异常安全。关注威哥爱编程,了解更多全栈开发技巧。 先赞再看后评论,腰缠万贯财进门。
189 0
|
4月前
|
XML 网络协议 API
超级好用的C++实用库之服务包装类
通过本文对Boost.Asio、gRPC和Poco三个超级好用的C++服务包装类库的详细介绍,开发者可以根据自己的需求选择合适的库来简化开发工作,提高代码的效率和可维护性。每个库都有其独特的优势和适用场景,合理使用这些库可以极大地提升C++开发的生产力。
94 11
|
7月前
|
安全 程序员 编译器
【实战经验】17个C++编程常见错误及其解决方案
想必不少程序员都有类似的经历:辛苦敲完项目代码,内心满是对作品品质的自信,然而当静态扫描工具登场时,却揭示出诸多隐藏的警告问题。为了让自己的编程之路更加顺畅,也为了持续精进技艺,我想借此机会汇总分享那些常被我们无意间忽视却又导致警告的编程小细节,以此作为对未来的自我警示和提升。
996 30
|
6月前
|
自然语言处理 编译器 Linux
告别头文件,编译效率提升 42%!C++ Modules 实战解析 | 干货推荐
本文中,阿里云智能集团开发工程师李泽政以 Alinux 为操作环境,讲解模块相比传统头文件有哪些优势,并通过若干个例子,学习如何组织一个 C++ 模块工程并使用模块封装第三方库或是改造现有的项目。
586 56
|
4月前
|
存储 算法 安全
基于哈希表的文件共享平台 C++ 算法实现与分析
在数字化时代,文件共享平台不可或缺。本文探讨哈希表在文件共享中的应用,包括原理、优势及C++实现。哈希表通过键值对快速访问文件元数据(如文件名、大小、位置等),查找时间复杂度为O(1),显著提升查找速度和用户体验。代码示例展示了文件上传和搜索功能,实际应用中需解决哈希冲突、动态扩容和线程安全等问题,以优化性能。
|
7月前
|
Java
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
本文深入探讨了Java中方法参数的传递机制,包括值传递和引用传递的区别,以及String类对象的不可变性。通过详细讲解和示例代码,帮助读者理解参数传递的内部原理,并掌握在实际编程中正确处理参数传递的方法。关键词:Java, 方法参数传递, 值传递, 引用传递, String不可变性。
136 1
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
|
6月前
|
Ubuntu Linux Shell
C++ 之 perf+火焰图分析与调试
【11月更文挑战第6天】在遇到一些内存异常的时候,经常这部分的代码是很难去进行分析的,最近了解到Perf这个神器,这里也展开介绍一下如何使用Perf以及如何去画火焰图。
284 5