C++之STL库:string类(用法列举和总结)

简介: C++之STL库:string类(用法列举和总结)

前言

       大家在学习STL库的时候一定要学会看英文文档,俗话说熟能生巧,所以还得多练!在使用string类之前,要包含头文件#include <string>和using namespace std;

文档链接:string - C++ Reference

一、string——构造相关操作

1. string(); (常用)

构造一个空字符串

string s1;

2. string(const char *s); (常用)

使用字符串构造一个实例化对象

string s2("hello world");

3. string(const string& str); (常用)

使用string的实例化对象去拷贝构造另外一个实例化对象

string s2("hello world");
string s3(s2);

4. string& operator=(const string& str); (常用)

string s2("hello world");
string s4 = s2;

5. string& operator=(const char *s); (常用)

string s5 = "hello world";

6. string& operator=(char c);

这里有一点需要注意,赋值运算符重载和拷贝构造的区别,两个对象都是定义之后的=是赋值运算符重载,如果是在定义的时候的=,属于拷贝构造;

所以代码1是不正确的:因为这是拷贝构造,而在拷贝构造这里,没有将一个字符拷贝给string类的函数实现

正确的写法:

    string s6;
    s6 = 'x';

7. string (const string& str, size_t pos, size_t len = npos);

拷贝str,在pos的下标开始,拷贝len个长度。

string s7 = "hello world";
string s8(s7, 0, 3);

8. string (const char* s, size_t n);

从s上拷贝前n个字符

string s9("hello world", 4);

9. string (size_t n, char c);

拷贝n个一样的字符

string s10(10, 'x');

10. string (InputIterator first, InputIterator last);

用迭代器拷贝,first为头,last为尾,拷贝first<= string <last,也就是拷贝从first位置开始,在last前一个位置停下来,不拷贝last位置;(默认迭代器的end是在\0位置)

    string s11 = "hello world";
    string s12(s11.begin(), s11.end()-1);

二、string——打印相关操作

可以从键盘上输入字符串,但是遇到空格就结束输入

    string s1;
    cin >> s1;
    cout << s1 << endl;

2. 输出字符串cout

将字符串的内容打印到显示器上

3. 获取字符串getline

从流中获取字符串,输入空格不会停止

    string s1;
    getline(cin, s1);
    cout << s1 << endl;

三、string——访问和遍历相关操作

1. char& operator[] (size_t pos);

通过下标访问字符串元素

    string s1 = "hello world";
    cout << s1[0] << endl;

2.  char& at (size_t pos);

跟下标访问一样,只是报错的方式不同;

    string s1 = "hello world";
    cout << "字符串第5个字符为:" << s1.at(4) << endl;

3. iterator begin();和 iterator end();

begin获取字符串第一个字符的迭代器(可以理解取第一个字符的地址)

end获取最后一个字符的下一个位置的迭代器(可以理解取最后一个有效字符下一个位置的地址)

    string s1 = "hello world";
    string::iterator begin = s1.begin(); 
    string::iterator end = s1.end();

可以像指针那样的遍历

    string s1 = "hello world";
    string::iterator begin = s1.begin();
    string::iterator end = s1.end();
    while(begin < end)
    {
        cout << *begin << ' ';
        ++begin;
    }
    cout << endl;

也可以访问第几个位置的元素,但是一般用下标访问了

    string s1 = "hello world";
    string::iterator begin = s1.begin();
    string::iterator end = s1.end();
    cout << "访问第1个元素为:" << *begin << endl;
    cout << "访问第5个元素为:" << *(begin + 4) << endl;
    cout << "访问倒数第3个元素为:" << *(end - 3) << endl;

4. reverse_iterator rbegin();和 reverse_iterator rend();

rbegin:指向的是最后一个有效字符的迭代器,从后往前访问;

rend:指向的是第一个字符之前的迭代器,从前往后访问;

    string s1 = "hello world";
    string::reverse_iterator  rb = s1.rbegin();
    string::reverse_iterator re = s1.rend();
    while(rb < re)
    {
        cout << *rb << ' ';
        ++rb;
    }

5. 范围for遍历

很简洁,但是底层依旧是迭代器;

    string s1 = "hello world";
    for(auto e : s1)
    {
        cout << e << ' ';
    }
    cout << endl;

四、string——容量相关操作

1. size

计算字符串的长度,以字节为单位

string s1 = "hello world";
int len = s1.size();
cout << len << endl;

2. capacity

       返回当前为字符串已经分配的空间大小,以字节为单位,这个空间表示出来的是给有效字符存的空间;


       但是实际的空间大小是比capacity表示出来的多一个空间,是存\0的;

分配的空间会大于字符串的size,但是分配的空间有可能不同,这取决于不同的编译器;

string s1 = "hello world";
cout << s1.capacity() << endl;

3. empty

判断字符串是否为空串:为空返回true(非0),不为空,返回false(0)

    string s1 = "hello world";
    cout << s1.empty() << endl;
    string s2;
    cout << s2.empty() << endl;

4. clear

只清空字符串的有效内容,不销毁空间;清空内容之后,size为0,capacity不变

    string s3 = "hello world";
    cout << "清空之前的容量:" << s3.capacity() << endl;
    cout << "清空之前的长度:" <<s3.size() << endl;
    s3.clear();
    cout << "清空之后的容量:" << s3.capacity() << endl;
    cout << "清空之后的长度:" <<s3.size() << endl;

5. reserve

为字符串保留空间


规则:

1. 扩容:当保留的空间 > capacity,认为扩容。每个编译器扩容的空间是不同的,总体上看就是:实际扩容下的空间≥要保留的空间;

2. 缩容:当保留的空间 < capacity ,认为缩容。有的编译器不会缩容,有的编译器会缩容,如果保留的空间<size,只缩容到size大小。

    string s4 = "hello world";
    cout << "扩容之前的容量:" << s4.capacity() << endl;
    s4.reserve(100);
    cout << "扩容之后的容量:" << s4.capacity() << endl;

    string s4 = "hello world";
    cout << "缩容之前的容量:" << s4.capacity() << endl;
    s4.reserve(2);
    cout << "缩容之后的容量:" << s4.capacity() << endl;

6. resize

void resize (size_t n);
void resize (size_t n, char c);

将有效字符的个数该成n个;

n > capacity :size = n ,capacity ≥ n,若提供c,则后面全为c字符,若没提供,则为‘\0’;

并不是\0就是无效字符,对于有效字符的设定是根据在0~size-1之间的都是有效字符;

    string s5 = "hello world";
    cout << s5 << endl;
    cout << "调整有效字符之前的容量:" << s5.capacity() << endl;
    cout << "调整有效字符之前的长度:" <<s5.size() << endl;
    s5.resize(30);
    cout << s5 << endl;
    cout << "调整有效字符之后的容量:" << s5.capacity() << endl;
    cout << "调整有效字符之后的长度:" <<s5.size() << endl;

    string s5 = "hello world";
    cout << s5 << endl;
    cout << "调整有效字符之前的容量:" << s5.capacity() << endl;
    cout << "调整有效字符之前的长度:" <<s5.size() << endl;
    s5.resize(30, 'x');
    cout << s5 << endl;
    cout << "调整有效字符之后的容量:" << s5.capacity() << endl;
    cout << "调整有效字符之后的长度:" <<s5.size() << endl;

size < n < capacity ,size = n,capacity不变;若提供c,则后面全为c字符,若没提供,则为‘\0’;

n < size ,size = n ,删数据,保留前n个有效字符,capacity不变;

五、string——增加操作

1. string& operator+= (char c);

尾插字符

    string s1 = "hello world";
    cout << s1 << endl;
    s1 += 'x';
    cout << s1 << endl;

2. string& operator+= (const string& str);

尾插字符串

    string s1 = "hello world";
    cout << s1 << endl;
    s1 += s1;
    cout << s1 << endl;

3. string& operator+= (const char* s);

尾插字符串

    string s1 = "hello world";
    cout << s1 << endl;
    s1 += " hello CSDN";
    cout << s1 << endl;

4. string& insert (size_t pos, const string& str);

在pos位置之前插入字符串

    string s1 = "hello world";
    string s2 = "CSDN";
    cout << "插入之前:" << s1 << endl;
    s1.insert(1, s2);
    cout << "插入之后:" << s1 << endl;

更多的应用:string::insert - C++ Reference

六、string——删除操作

1. string& erase (size_t pos = 0, size_t len = npos);

从pos位置删字符,删 len个字符;


npos代表-1,len为size_t类型,为无符号类型,就会被转换为整型的最大值,所以len为整型最大值,在不提供实参,就默认为npos;

    string s1 = "hello world";
    cout << "删除之前:" << s1 << endl;
    s1.erase(1,3);
    cout << "删除之后:" << s1 << endl;

2. iterator erase (iterator p);

删除迭代器所处的位置的字符

    string s1 = "hello world";
    cout << "删除之前:" << s1 << endl;
    s1.erase(s1.begin());
    cout << "删除之后:" << s1 << endl;

3.  iterator erase (iterator first, iterator last);

删除两个迭代器之间的字符,包括first,不包括last,[first, last)

    string s1 = "hello world";
    cout << "删除之前:" << s1 << endl;
    s1.erase(s1.begin(), s1.end()-1);
    cout << "删除之后:" << s1 << endl;

七、string——查找操作

在pos位置向后查找str这个string类的对象,返回找到的字符串的第一个位置的下标,没找到就返回npos
size_t find (const string& str, size_t pos = 0) const;
在pos位置向后查找s这个字符串,返回找到的字符串的第一个位置的下标,没找到就返回npos
size_t find (const char* s, size_t pos = 0) const;
在pos位置向后找,找s的前n个字符,找到返回第一个位置的下标,找不到返回npos
size_t find (const char* s, size_t pos, size_t n) const;
在pos位置向后查找字符c,返回找到的字符位置的下标,没找到就返回npos
size_t find (char c, size_t pos = 0) const;

显示详细信息

具体查看:hstring::find - C++ Reference

rfind就是从后往前找

八、string——构造子串

意思就是构造一个子串,从pos位置开始,往后len个字符都构造;

    string s2 = "hello world";
    size_t n = s2.find('w', 0);
    string s3 = s2.substr(n,s2.size() - n);
    cout << s2 << endl;
    cout << s3 << endl;

九、string——比较操作

大家试着去官网去查查,一定要熟悉英文文献哦~

relational operators (string) - C++ Reference

十、好用的函数

1. 字符串转换整数

to_string - C++ Reference

2. 整数转换字符串

<string> - C++ Reference

十一、不同的编码要使用对应的string

UTF-8 string
UTF-16 u16string
UTF-32 u32string
宽字符(双字节字符 wstring


相关文章
|
4月前
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
114 2
|
1月前
|
对象存储 C++ 容器
c++的string一键介绍
这篇文章旨在帮助读者回忆如何使用string,并提醒注意事项。它不是一篇详细的功能介绍,而是一篇润色文章。先展示重载函数,如果该函数一笔不可带过,就先展示英文原档(附带翻译),最后展示代码实现与举例可以直接去看英文文档,也可以看本篇文章,但是更建议去看英文原档。那么废话少说直接开始进行挨个介绍。
43 3
|
4月前
|
存储 算法 C++
【c++丨STL】map/multimap的使用
本文详细介绍了STL关联式容器中的`map`和`multimap`的使用方法。`map`基于红黑树实现,内部元素按键自动升序排列,存储键值对,支持通过键访问或修改值;而`multimap`允许存在重复键。文章从构造函数、迭代器、容量接口、元素访问接口、增删操作到其他操作接口全面解析了`map`的功能,并通过实例演示了如何用`map`统计字符串数组中各元素的出现次数。最后对比了`map`与`set`的区别,强调了`map`在处理键值关系时的优势。
221 73
|
1月前
|
存储 编译器 C语言
关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论
你真的了解string的'\0'么?你知道创建一个string a("abcddddddddddddddddddddddddd", 16);这样的string对象要创建多少个对象么?你知道string与vector进行扩容时进行了怎么的操作么?你知道怎么求Vector 最大 最小值 索引 位置么?
33 0
|
4月前
|
存储 算法 C++
【c++丨STL】set/multiset的使用
本文深入解析了STL中的`set`和`multiset`容器,二者均为关联式容器,底层基于红黑树实现。`set`支持唯一性元素存储并自动排序,适用于高效查找场景;`multiset`允许重复元素。两者均具备O(logN)的插入、删除与查找复杂度。文章详细介绍了构造函数、迭代器、容量接口、增删操作(如`insert`、`erase`)、查找统计(如`find`、`count`)及`multiset`特有的区间操作(如`lower_bound`、`upper_bound`、`equal_range`)。最后预告了`map`容器的学习,其作为键值对存储的关联式容器,同样基于红黑树,具有高效操作特性。
166 3
|
4月前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
115 11
|
4月前
|
Java
课时14:Java数据类型划分(初见String类)
课时14介绍Java数据类型,重点初见String类。通过三个范例讲解:观察String型变量、&quot;+&quot;操作符的使用问题及转义字符的应用。String不是基本数据类型而是引用类型,但使用方式类似基本类型。课程涵盖字符串连接、数学运算与字符串混合使用时的注意事项以及常用转义字符的用法。
108 9
|
4月前
|
存储 JavaScript Java
课时44:String类对象两种实例化方式比较
本次课程的主要讨论了两种处理模式在Java程序中的应用,直接赋值和构造方法实例化。此外,还讨论了字符串池的概念,指出在Java程序的底层,DOM提供了专门的字符串池,用于存储和查找字符串。 1.直接赋值的对象化模式 2.字符串池的概念 3.构造方法实例化
|
8月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
238 2
|
9月前
|
Java
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
本文深入探讨了Java中方法参数的传递机制,包括值传递和引用传递的区别,以及String类对象的不可变性。通过详细讲解和示例代码,帮助读者理解参数传递的内部原理,并掌握在实际编程中正确处理参数传递的方法。关键词:Java, 方法参数传递, 值传递, 引用传递, String不可变性。
166 1
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性