5.string
一.string简介
1.底层原理:
string的底层实现是基于动态分配的字符数组,这个字符数组中存储了字符串中的每个字符。string类的设计将字符串的操作封装成了各种成员函数,这些函数会直接操作这个字符数组,从而实现字符串的各种操作。
2. 功能特点:
- 可变性:string类中的字符串可以随意修改。
- 动态分配:string类中的字符串的内存是动态分配的,这意味着可以根据实际需要进行内存的分配和释放。
- 安全性:string类中的各种操作会自动检查越界错误,并且不会导致内存泄漏等问题。
- 高效性:string类中的各种操作都经过优化,能够在不损失效率的情况下实现各种字符串操作。
3.使用场景:
string类适合于以下情况:
- 需要频繁修改字符串内容的情况。
- 需要进行各种字符串操作,如字符串查找、替换、插入、删除等。
- 需要进行字符串和其他类型的相互转换的情况,如将字符串转换成整数、将整数转换成字符串等。
- 需要处理中文字符的情况,因为string类内部使用的是UTF-8编码,可以处理Unicode字符。
- 需要在程序中处理大量字符串的情况,因为string类的内部实现对于内存的分配和释放做了很好的优化,能够避免内存泄漏等问题。
- 与char*字符串相比,标准库中的string类不必担心内存是否足够、字符串长度等问题,而且作为一个类出现,他集成的操作函数非常丰富,足以完成大多数情况下的需要;
- 头文件:
#include <string>
// 是< string >不是<string.h>。
2.常用操作函数汇总:
1) =, s.assign():赋以新值
2) swap():交换两个字符串的内容
3) +=, s.append(str), s.push_back():将字符串str追加到当前字符串的末尾。
4) s.insert(pos, str):在当前字符串的pos位置插入字符串str。
5) s.erase(pos, len):从当前字符串的pos位置开始,删除长度为len的子串。
6) s.clear():删除全部字符
7) s.replace(pos, len, str):从当前字符串的pos位置开始,用字符串str替换长度为len的子串。
8) + :串联字符串
9) == , != , <, <= , >, >= , compare():比较字符串
10) size(), length() :获取字符串的长度。
11) max_size() :返回字符的可能最大个数
12) s.empty() :判断字符串是否为空
13) s.capacity() :返回重新分配之前的字符容量
14) reserve() :保留一定量内存以容纳一定数量的字符
15)[], at() :存取单一字符
16) >> , getline() :从stream读取某值
17) << :将谋值写入stream
18) copy() :将某值赋值为一个C_string
19) c_str() :返回一个指向正规C字符串(C_string)的指针 内容与本string串相同 有’\0’
20) data() :将内容以字符数组形式返回 无’\0’
21) s.substr(pos, len) :返回从pos位置开始,长度为len的子串。
22) begin() end() :提供类似STL的迭代器支持
23) rbegin() rend() :逆向迭代器
24) get_allocator() :返回配置器
25) find(str, pos):在当前字符串中从pos位置开始查找字符串str,返回其第一次出现的位置,如果未找到则返回std::string::npos。
26) compare(str):将当前字符串和字符串str进行比较,如果两者相等则返回0,如果当前字符串小于字符串str则返回负数,如果当前字符串大于字符串str则返回正数
二.string常用实例
1.字符串构造(初始化)
1.string构造函数的几种形式:
1) string str:生成空字符串
2) string s(str):生成字符串为str的复制品
3) string s(str, strbegin, strlen):将字符串str中从下标strbegin开始、长度为strlen的部分作为字符串初值
4) string s(cstr, char_len):以C_string类型cstr的前char_len个字符串作为字符串s的初值
5) string s(num, c):生成num个c字符的字符串
6) string s(str, stridx):将字符串str中从下标stridx开始到字符串结束的位置作为字符串初值
7) s.~string():将字符串重置为空字符串
2.string构造实例:
#include "pch.h"
#include <iostream>
#include <string>
using namespace std;
void test1(){
string str1; //生成空字符串
getline(cin, str1); //键盘输入str1
string str2("123456789"); //生成"1234456789"的复制品
string str3("12345", 0, 3);//结果为"123"
string str4("0123456", 5); //结果为"01234"
string str5(5, '1'); //结果为"11111"
string str6(str2, 2); //结果为"3456789"
cout << "str1:" << str1 << endl;
cout << "str2:" << str2 << endl;
cout << "str3:" << str3 << endl;
cout << "str4:" << str4 << endl;
cout << "str5:" << str5 << endl;
cout << "str6:" << str6 << endl;
str6.~string(); //将str6置为空字符串
cout << "new str6:" << str6 << endl;
}
int main(){
test1();
return 0;
}
2.char*(char[])、int与string的相互转换(c_str)
void test2() {
const char* str1 = "abcdefg123";
char str2[] = "hijklmn456";
string STR3 = "hello";
int num4 = 12345;
string STR5 = "98765";
string STR1 = str1; //将char*转换为string
string STR2 = str2; //将char[]转换为string
const char *str3 = STR3.c_str(); //将string转换为const char*
string STR4 = to_string(num4); //将int转换为string
int num5 = atoi(STR5.c_str()); //将string转换为int
cout << "STR1 is: " << STR1 << endl;
cout << "STR2 is: " << STR2 << endl;
cout << "str3 is: " << str3 << endl;
cout << "STR4 is: " << STR4 << endl;
cout << "num5 is: " << num5 << endl;
}
3.字符串大小和容量(size、max_size、capacity):
1.函数介绍:
1) size()和length():返回string对象的字符个数,他们执行效果相同
2) max_size():返回string对象最多包含的字符数,超出会抛出length_error异常
3) capacity():重新分配内存之前,string对象能包含的最大字符数
2.用例:
void test3(){
string s("1234567");
cout << "size=" << s.size() << endl;
cout << "length=" << s.length() << endl;
cout << "max_size=" << s.max_size() << endl;
cout << "capacity=" << s.capacity() << endl;
}
4.字符串比较(>,>=,<,<=,==,!=、compare):
1. C ++字符串支持常见的比较操作符(>,>=,<,<=,==,!=),甚至支持string与C-string的比较(如 str<”hello”)。
在使用>,>=,<,<=这些操作符的时候是根据“当前字符特性”将字符按字典顺序进行逐一得 比较。字典排序靠前的字符小,
比较的顺序是从前向后比较,遇到不相等的字符就按这个位置上的两个字符的比较结果确定两个字符串的大小(前面减后面)
同时,string (“aaaa”) <string(aaaaa)。
2. 另一个功能强大的比较函数是成员函数compare()。他支持多参数处理,支持用索引值和长度定位子串来进行比较。
他返回一个整数来表示比较结果,返回值意义如下:0:相等 1:大于 -1:小于 (A的ASCII码是65,a的ASCII码是97)
void test4(){
// (A的ASCII码是65,a的ASCII码是97)
// 前面减去后面的ASCII码,>0返回1,<0返回-1,相同返回0
string A("aBcd");
string B("Abcd");
string C("123456");
string D("123dfg");
// "aBcd" 和 "Abcd"比较------ a > A
cout << "A.compare(B):" << A.compare(B) << endl; // 结果:1
// "cd" 和 "Abcd"比较------- c > A
cout << "A.compare(2, 3, B):" << A.compare(2, 3, B) << endl; // 结果:1
// "cd" 和 "cd"比较
cout << "A.compare(2, 3, B, 2, 3):" << A.compare(2, 3, B, 2, 3) << endl; // 结果:0
// 由结果看出来:0表示下标,3表示长度
// "123" 和 "123"比较
cout << "C.compare(0, 3, D, 0, 3)" << C.compare(0, 3, D, 0, 3) << endl; // 结果:0
}
5.字符串切割、拼接(substr、append、+) :
void test5() {
string s = "abcdefg";
//s.substr(pos1,n)返回字符串位置为pos1后面的n个字符组成的串
string s1 = s.substr(1, 5);//bcdef
cout << "s1=" << s1 << endl;
//s.substr(pos)//得到一个pos到结尾的串
string s2 = s.substr(4);//efg
cout << "s2=" << s2 << endl;
// 方法一:append()
s1.append("666");//bcdef666
cout << "s1=" << s1 << endl;
// 方法二:+
s2+="777";//efg777
cout << "s2=" << s2 << endl;
}
6.字符串等增、删(push_back、insert、erase) :
void test6() {
string s1, s2("This is an example sentence.");
// 尾插一个字符
s1.push_back('a');
s1.push_back('b');
cout << "s1:" << s1 << endl; // s1:ab
// insert(pos,char):在指定的位置pos前插入字符char
s1.insert(s1.begin(), '9');
s1.insert(3, "defgh");
cout << "s1:" << s1 << endl; // s1:9abdefgh
//删除字符串位置第十个后面的8个字符
s2.erase(10, 8);
cout << "s2:" << s2 << endl;
//删除迭代器指向的字符
s2.erase(s2.begin() + 9);
cout << "s2:" << s2 << endl;
//删除迭代器范围的字符
s2.erase(s2.begin() + 5, s2.end() - 9);
cout << "s2:" << s2 << endl;
}
7.字符串的查(find) :
void test7(){
string s("dog bird chicken bird cat");
//字符串查找-----找到后返回首字母在字符串中的下标
// 1. 查找一个字符串
cout << s.find("chicken") << endl; // 结果是:9
// 2. 从下标为6开始找字符'i',返回找到的第一个i的下标
cout << s.find('i', 6) << endl; // 结果是:11
// 3. 从字符串的末尾开始查找字符串,返回的还是首字母在字符串中的下标
cout << s.rfind("chicken") << endl; // 结果是:9
// 4. 从字符串的末尾开始查找字符
cout << s.rfind('i') << endl; // 结果是:18-------因为是从末尾开始查找,所以返回第一次找到的字符
// 5. 在该字符串中查找第一个属于字符串s的字符
cout << s.find_first_of("13br98") << endl; // 结果是:4---b
// 6. 在该字符串中查找第一个不属于字符串s的字符------先匹配dog,然后bird匹配不到,所以打印4
cout << s.find_first_not_of("hello dog 2006") << endl; // 结果是:4
cout << s.find_first_not_of("dog bird 2006") << endl; // 结果是:9
// 7. 在该字符串最后中查找第一个属于字符串s的字符
cout << s.find_last_of("13r98") << endl; // 结果是:19
// 8. 在该字符串最后中查找第一个不属于字符串s的字符------先匹配t--a---c,然后空格匹配不到,所以打印21
cout << s.find_last_not_of("teac") << endl; // 结果是:21
}
8.字符串的改(replace) :
1) string& replace(size_t pos, size_t n, const char *s):将当前字符串从pos索引开始的n个字符,替换成字符串s
2) string& replace(size_t pos, size_t n, size_t n1, char c):将当前字符串从pos索引开始的n个字符,替换成n1个字符c
3) string& replace(iterator i1, iterator i2, const char* s):将当前字符串[i1,i2)区间中的字符串替换为字符串s
void test8(){
string s1("hello,world!");
cout <<"s1="<<s1<<",长度为:"<< s1.size() << endl;
s1.replace(s1.size() - 1, 1, 1, '.'); // 结果:hello,world.
// 这里的6表示下标 5表示长度
s1.replace(6, 5, "girl"); // 结果:hello,girl.
// s1.begin(),s1.begin()+5 是左闭右开区间
s1.replace(s1.begin(), s1.begin() + 5, "boy"); // 结果:boy,girl.
cout << s1 << endl;
}
9.其他(排序sort、大小写转换) :
void test9() {
string s = "cdefba";
//排序sort用法:
sort(s.begin(), s.end());
cout << "s:" << s << endl; // 结果:abcdef
//字符串大小写转换
for (int i = 0; i < s.size(); i++)
s[i] = toupper(s[i]); //(转小写:tolower)
cout << "s:" << s << endl; // 结果:ABCDEF
}