C++ STL容器 —— string 用法详解

C++ STL容器 —— string 用法详解

写在前面:近期正在学习C++的STL容器,因此在这里做一下日志记录,主要介绍一些容器基本成员函数的用法, 配上实际用例,并不涉及原理。但别人的博客终究是别人的, 最好自己上手操作一下.
写的不好, 请大神手下留情.

下面说的 “运行之后” 表示: 运行上个语句之后的结果.
一行如果说的太长的话, 就得拖动下面的进度条才能看到后面的内容, 非常麻烦
因此将一段话分成了多行,就像现在这种形式

简介

头文件: # include < string >
一个专门存储和处理字符类型的容器, 具有强大的功能, 我理解为:vector < char >
点击前往: vector 用法详解

构造函数

string str, str1;
//定义空 string 容器

string str2("abcde");//1
//定义新容器, 将 “abcde” 作为初值

string str3 = "abcde";
//同上

string str4{ "abcde" };//2
//同上

string str5 = { "abcde" };
//同上

string str6{ 'a','b','c','d','e' };
//同上

string str7(6, 's');
//定义新容器, 将 6 个 ‘s’ 作为初值

string str8(str);
//定义新容器 str8, 拷贝 str 所有的元素

string str9 = str;
//同上

string str10(str, 2);
//定义新容器 str10, 拷贝 str[2]~str[n-1]

string str11(str, 2, 3);
// 定义新容器 str11, 拷贝 str[2]~str[2+3-1]

string str12(str.begin(), str.end());
//定义新容器 str12, 拷贝区间内元素

1 和 2 的区别:括号不同
小括号是复制的作用, 是将"abcde"复制给 str
大括号是赋值的作用, 是给 str 赋值 “abc”

访问/赋值

迭代器

包括:begin、end、rbegin、rend、cbegin、cend、crbegin、crend
使用方法

auto it = str.begin();//用 *it 访问\

简介
str.begin(); 返回迭代器, 指向第一元素
str.end(); 返回迭代器, 指向最末元素的下一个位置
str.cbegin(); 返回迭代器, 指向第一元素, 类型为const
str.rbegin(); 返回反向迭代器, 指向反向迭代的第一元素
str.rend(); 返回反向迭代器, 指向反向迭代的最末元素的下一个位置
str.crbegin(); 返回反向迭代器, 指向反向迭代的第一元素, 类型为const

例: 使用正向遍历str变量

string str="abcdefghijklmn";
for(auto it=str.begin();it!=str.end();it++){
//注意这里是不等于end, 而不是小于end
	cout<<*it<<endl;
}
输出结果为: 
abcdefghijklmn

例: 反向遍历str变量

string str="abcdefghijklmn";
for(auto it=str.rbegin();it!=str.rend();it++){
//注意这里还是it++, 而不是it--
	cout<<*it<<endl;
}
输出结果为: 
nmlkjihgfedcba

begin和rbegin的区别
str.begin()返回迭代器,指向容器内的第一元素
str.rbegin()返回逆序迭代器,指向容器内的最后一个元素

begin和cbegin的区别
可以通过str.begin()修改容器内元素的值
不能通过str.cbegin()修改容器内元素的值

下标/at

支持下标 [] 和 at 函数随机访问容器内字符
str[id]; 返回下标为 id 的字符, 不检查是否越界
str.at(id); 返回下标为 id 的字符, 如果越界抛出异常

assign (赋值函数)
str.assign(6, 's');
//将 6 个 's' 赋值给 str
//例:str="abcde"
//运行之后 str="ssssss"

str.assign(str1);
//将 str1 赋值给 str
//例:str="abcde", str1="123"
//运行之后 str="123"

str.assign(str1, 2);
//将 str1[2]~str1[n-1] 赋值给 str
//例:str="abc", str1="123456"
//运行之后 str="3456"

str.assign(str1, 2, 3);
//将 str1[2]~str1[2+3-1] 赋值给 str
//例:str="abc", str1="123456"
//运行之后 str="345"

str.assign(str1.begin()+1, str1.end()-1);
//将区间内的元素赋值给 str
//例:str="abc", str1="123456"
//运行之后 str="2345"
连接符
  1. =:字符串赋值
    例: s1为空, 则: s1=“abc"之后, s1变为"abc”

  2. +和 +=:连接字符串
    用的较多的是 +=
    例: s1=“abc”, s2=“123”, 则: s1+=s2之后, s1 变为 “abc123”, s2不变
    例: s1=“abc”, 则: s1+="string"之后, s1 变为 “abcstring”
    例: s1=“abc”, 则: s1+='p’之后, s1 变为 “abcp”

  3. <、>=、< 和 <=:字符串比较 (例如a < b)
    按字典序判断字符串的大小, 并返回判断结果.
    例: s1=“abc”, s2=“abb”, 则 s1<s2 返回 false
    例: s1=“abc”, s2=“abb”, 则 s1>s2 返回 true

  4. ==、!=:比较字符串
    判断字符串是否相同
    例: s1=“abc”, s2=“abb”, 则 s1 ==s2 返回 false

  5. <<、>>:输出、输入字符串
    直接使用cin和cout输出
    string str;
    cin>>str;
    cout<<str;

swap (交换函数)
str.swap(str1);
// 交换两个容器的内容
//例:str="abc", str1="123"
//运行之后, str="123", str1="abc"

常用函数

str.push_back('s');
//在 str 末尾添加字符 's'
//例:str="abc"
//运行之后, str="abcs"

str.pop_back();
//删除最后一个字符
//例:str="abc"
//运行之后, str="ab"

str.front();
//返回第一元素
//例:str="abc"
//str.front()就等于 'a'

str.back();
//返回最末元素
//例:str="abc"
//str.back()就等于 'c'

str.clear();
//清空容器

str.empty();
//容器为空返回 true, 否则返回 false

长度/空间/容量相关函数

str.length();
//返回字符串 str 的长度
//例: str="abc"
//返回 3

str.size();
//返回容器内目前的元素个数
//例: str="abc"
//返回 3

str.max_size();
//返回元素个数 size 的最大值
//返回一个数字, 根据编译环境的不同, 这个数字也不同, 基本没什么用.

str.resize(3);
//设置 str 的 size,只影响 size,设置之后size=3
//例:str="abcdefg"
//运行之后 str="abc", 如果尺寸变小,多余的部分截掉
//例:str="ab"
//运行之后 str="ab ", 如果尺寸变大,新空间用空格代替

str.resize(4, 's');
//设置 str 的 size,如果尺寸变大,新空间全用字符 's' 代替
//例: str="ab"
//运行之后 str="abss"

str.capacity();
//返回重新分配内存前 str 可以容纳的字符数,至少比size大,
//大小只能为:16*n-1
//他的值只能等于16,31,47,,,,,16*n-1
//例: str="abc"
//返回 15
//例: str="abcabcabcabcabcabc"
//返回 31

str.reserve(16);
//设置 str 的 capacity,只影响 capacity。
//设置之后, str.capacity()>=16, 即 str.capacity()=31
//因为需要遵循16*n-1的原则
//例: str="abc", 此时 str.capacity()=15
//执行之后, str.capacity()=31, 因为要大于等于16, 还得符合条件

添加元素

insert (插入函数)
str.insert(2, 3, 's');
//在位置之前插入 3 个字符 's'
//例: str="abc"
//运行之后, str="absssc"

str.insert(2, "123");
//在位置之前插入字符串 “123”, 返回str
//例: str="abc"
//运行之后, str="ab123c"

str.insert(2, str1);
//在位置之前插入 str1
//例: str="abc", str1="123"
//运行之后, str="ab123c"

str.insert(2, str1, 3);
//在位置之前插入 str1[3]~str1[n-1]
//例: str="abc", str1="123456"
//运行之后, str="ab456c"

str.insert(2, str1, 3, 4);
//在位置之前插入 str1[3]~str1[3+4-1]
//例: str="abc", str1="123456789"
//运行之后, str="ab4567c"

str.insert(str.end(), 's');
//在位置之前插入字符 's', 返回新元素的第一个位置
//例: str="abc"
//运行之后, str="absc"

str.insert(str.end(), 3, 's');
//在位置之前插入 3 个字符 s
//例: str="abc"
//运行之后, str="abcsss"

str.insert(str.end(), str1.begin(), str1.end());
//在位置之前插入 str1 区间内的元素
//例: str="abc", str1="123456"
//运行之后, str="abc123456"
append (连接函数)
str.append(3, 's');
//在 str 末尾添加 3 个字符 's'
//例:str="abc"
//运行之后 str="abcsss"

str.append(str1);
// 在 str 末尾添加 str1
//例:str="abc", str1="123"
//运行之后 str="abc123"

str.append(str1, 2);
//在 str 末尾添加 str1[2]~str1[n-1]
//例:str="abc", str1="123456"
//运行之后 str="abc3456"

str.append(str1, 2, 3);
//在 str 末尾添加 str1[2]~str1[2+3-1]
//例:str="abc", str1="123456"
//运行之后 str="abc345"

str.append(str1.begin()+1,str1.end()-1);
//将 str1 区间内的元素添加到 str 末尾
//例:str="abc", str1="123456"
//运行之后 str="abc2345"

删除元素

erase (删除函数)
str.erase(3);
//删除 str[3]~str[n-1] , 返回 str
//例: str="0123456789"
//运行之后, str="012"

str.erase(3, 2);
//删除 str[3]~str[3+2-1] , 返回 str
//删除 str[3] 开始的 2 个字符
//例: str="0123456789"
//运行之后, str="01256789"

str.erase(str.begin());
//删除指向的元素, 返回迭代器, 指向下一元素
//例: str="abc"
//运行之后, str="bc", 返回指向字符 'b' 的迭代器


str.erase(str.begin(), str.end() - 1);
//删除区间内的元素, 返回迭代器, 指向下一元素
//例: str="abc"
//运行之后, str="c", 返回指向字符 'c' 的迭代器

str.erase(str.begin(), str.end());
//删除区间内的元素, 返回迭代器, 指向下一元素
//例: str="abc"
//运行之后, str=null, 删除的是所有元素

更改数据

replace (替换函数)

返回 str

str.replace(2,3,4,'s');
//将 str[2]~str[2+3-1] 替换成 4 个 ‘s’
//例: str="abcdefgh"
//运行之后, str="abssssfgh"

str.replace(2,3,ch);
//将 str[2]~str[2+3-1] 替换成 ch
//例: str="abcdefgh", ch="123456"
//运行之后, str="ab123456fgh"

str.replace(2,3,ch,4);
//将 str[2]~str[2+3-1] 替换成 ch的前 4 个字符
//例: str="abcdefgh", ch="123456"
//运行之后, str="ab1234fgh"

str.replace(2,3,ch,4,5);
//将 str[2]~str[2+3-1] 替换成 ch[4]~ch[4+5-1]
//例: str="abcdefgh", ch="1234567890123"
//运行之后, str="ab56789fgh"

str.replace(2,3,str1);
//将 str[2]~str[2+3-1] 替换成 str1
//例: str="abcdefgh", str1="123456"
//运行之后, str="ab123456fgh"
//例: str="abcdefgh", str1="12"
//运行之后, str="ab12fgh"

str.replace(2,3,str1,4);
//将 str[2]~str[2+3-1] 替换成 str1[4]~str1[n-1]
//例: str="abcdefgh", str1="123456789"
//运行之后, str="ab56789fgh"

str.replace(2,3,str1,4,5);
//将 str[2]~str[2+3-1] 替换成 str1[4]~str1[4+5-1]
//例: str="abcdefgh", str1="1234567890123"
//运行之后, str="ab56789fgh"

str.replace(str.begin(),str.end(),3,'s');
//将区间内的元素替换成 3 个 ‘s’
//例: str="abcd"
//运行之后, str="sss"

str.replace(str.begin(),str.end(),ch);
//将区间内的元素替换成 ch
//例: str="abcd", ch="123456"
//运行之后, str="123456"
str.replace(str.begin(),str.end(),ch,3);
//将区间内的元素替换成 ch 的前 3 个字符
//例: str="abcd", ch="123456"
//运行之后, str="123"

str.replace(str.begin(),str.end(),str1);
//将区间内的元素替换成 str1
//例: str="abcd", str1="123456"
//运行之后, str="123456"
copy (复制函数)

返回复制的字符数量

str.copy(ch, 3);
//将 ch 前 3 个字符替换成 str 的前 3 个字符
//例: str="abcde", ch="";
//执行之后, ch="abc", str不变:更改的是 ch 数组

str.copy(ch, 3, 2);
//将 ch 前 3 个字符替换成 str[2]~str[2+3-1]
//例: str="abcdefg", ch="123456";
//执行之后, ch="cde456"
//注意参数的位置: 2代表下标的位置, 3代表字符的数量
如果 ch 的长度太长, 后面的字符就不管了
大小写转换
transform(str.begin(), str.end(), str1.begin(), ::toupper);
//将 str 全部的英文转换为大写, 赋值给 str1
//str1.size() 必须大于等于 str.size()

transform(str.begin(), str.end(), str1.begin(), ::tolower);
//将 str 全部的英文转换为小写, 赋值给 str1

查找数据

find系列 (查找函数)

能找到返回下标,否则返回str.npos
包括六种:
find / rfind
find_first_of / find_first_not_of
find_last_of / find_last_not_of
其他五个函数的参数用法参考 find 函数

str.find('s');
// 返回字符 's' 在 str 中首次出现的位置
//例: str="sabcsabc"
//返回 0

str.find('s', 2);
// 返回字符 ‘s’ 在 str[2]~str[n-1] 中首次出现的位置
//例: str="sabcsabc"
//返回 4

str.find(ch);
//返回字符串 ch 在 str 中首次出现的位置
//例: str="abcabc", ch="bc"
//返回 1

str.find(ch, 2);
//返回 ch 在 str[2]~str[n-1] 中首次出现的位置
//例: str="abcabc", ch="bc"
//返回 4

str.find(ch, 2, 3);
//返回 ch[0]~ch[3-1] 在 str[2]~str[n-1] 中首次出现的位置
//返回 ch 前 3 个字符在 str[2]~str[n-1] 中首次出现的位置
//例: str="abcabcabc", str1="bcaaa"
//返回 4

str.find(str1);
//返回 str1 在 str 中首次出现的位置
//例: str="abcabc", str1="bc"
//返回 1

str.find(str1, 2);
//返回 str1 在 str[2]~str[n-1] 中首次出现的位置
//例: str="abcabc", str1="bc"
//返回 4

str.rfind(str1);
//反向查找 str1 在 str 中首次出现的位置
//例: str="abcabc", str1="bc"
//返回 4

str.rfind(str1,3);
//定义: 反向查找 str1 在 str[0]~str[3] 中首次出现的位置
//实际: 反向查找 str1 在 str[0]~str[3+str1.size()-1] 中首次匹配成功的位置
为什么会有两种解释呢, 可以看一下下面几个例子
//例: str="abcabcabc", str1="abc"
//1: str.rfind(str1,2); 返回 0
//2: str.rfind(str1,3); 返回 3
//3: str.rfind(str1,4); 返回 3
//4: str.rfind(str1,6); 返回 6
//其实 rfind 函数查找的是 str1 在 str 出现的位置
//例1相当于反向查找 abc 在 abcab 首次匹配成功的位置
//例2相当于反向查找 abc 在 abcabc 首次匹配成功的位置
//例3相当于反向查找 abc 在 abcabca 首次匹配成功的位置
//也就是说: 参数表达的界限是字符串出现位置的界限, 可以不包括字符串
//例1界限是 0~2, 返回的是 0
//例2界限是 0~3, 返回的是 3, str[3]~str[5]可以匹配成功
//注意字符串出现的位置与匹配成功的区别
//语文不太好, 说的不清楚, 可以自己写点代码试试

str.find_first_of(str1);
//返回 str1 中任意一个字符在 str 中首次出现的位置
//例: str="abcabc", str1="cb"
//返回 1
//因为在 str 中最先出现的是 str1 里面的 'b' 字符, 所以返回 'b' 的下标

str.find_first_not_of(str1);
//返回除 str1 以外的任意一个字符在 str 中首次出现的位置
//例: str="abcabc", str1="ca"
//返回 1
//因为在 str 中最先出现不在 str1 里面的字符是 'b', 所以返回 'b' 的下标

str.find_last_of(str1);
//返回 str1 中任意一个字符在 str 最后一次出现的位置
//就是反向查找, 原理和find_first_of一样
//例: str="abcabc", str1="ba"
//返回 4 (第二个 'b' 的下标)

str.find_last_not_of(str1);
//返回除 str1 以外的任意一个字符在 str 最后一次出现的位置
//反向查找, 原理和find_first_not_of一样
//例: str="abcabc", str1="cb"
//返回 3 (第二个 'a' 的下标)

find 和 find_first_of 的区别:
find 需要子串和父串全部匹配
find_first_of 只需匹配一个字符就可以
例: str=“abcabcabc”, str1=“cab”
str.find(str1) 返回 2, 因为需要完全匹配
str.find_first_of(str1) 返回 0, 因为 str1 中的字符 ‘a’ 在 str 中第一次出现的下标是 0

查找 str 中 str1 出现的所有位置
一个find函数的小例子

string str = "abcbcabcbc";
string str1 = "bc";
int position = 0;
int i = 1;
while ((position = str.find(str1, position)) != str.npos) {
	cout << "position  " << i << " : " << position << endl;
	position++;
	i++;
}
输出结果:
position  1 : 1
position  2 : 3
position  3 : 6
position  4 : 8

原理: 一直执行 find 函数, 每次查找的开头是上一次查找结果的下一个位置
substr (子串查找)
str.substr(2);
//返回 str[2]~str[n-1], 不对 str 进行操作
//例:str="abcde"
//str.substr(2) 就等于 "cde"

str.substr(2,5);
//返回 str[2]~str[2+5-1]
//例:str="abcdefghijklmn"
//str.substr(2,5) 就等于 "cdefg"
  • 19
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值