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"
连接符
-
=:字符串赋值
例: s1为空, 则: s1=“abc"之后, s1变为"abc” -
+和 +=:连接字符串
用的较多的是 +=
例: s1=“abc”, s2=“123”, 则: s1+=s2之后, s1 变为 “abc123”, s2不变
例: s1=“abc”, 则: s1+="string"之后, s1 变为 “abcstring”
例: s1=“abc”, 则: s1+='p’之后, s1 变为 “abcp” -
<、>=、< 和 <=:字符串比较 (例如a < b)
按字典序判断字符串的大小, 并返回判断结果.
例: s1=“abc”, s2=“abb”, 则 s1<s2 返回 false
例: s1=“abc”, s2=“abb”, 则 s1>s2 返回 true -
==、!=:比较字符串
判断字符串是否相同
例: s1=“abc”, s2=“abb”, 则 s1 ==s2 返回 false -
<<、>>:输出、输入字符串
直接使用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"