【STL——string容器部分】
引入
STL(Standard Template Library)是 C++ 标准库的核心组成部分,提供了一系列通用的模板类和函数,包括容器、算法、迭代器和函数对象。STL 的设计目标是提高代码复用性和开发效率,其核心思想是将数据结构和算法分离,通过迭代器作为桥梁实现泛型编程。
从根本上说,STL是一些“容器”的集合,这些“容器”有list,vector,set,map一大堆,STL也是算法和其他一些组件的集合。比如说中sort函数、中string类。
基本组成
STL从广义上讲分为三类:
- 容器(Container),是一种数据结构,如list,vector,和deques ,以模板类的方法提供。为了访问容器中的数据,可以使用由容器类输出的迭代器;
- 迭代器(Iterator),提供了访问容器中对象的方法。例如,可以使用一对迭代器指定list或vector中的一定范围的对象。迭代器就如同一个指针。
事实上,C++的指针也是一种迭代器。但是,迭代器也可以是那些定义了operator*()以及其他类似于指针的操作符地方法的类对象; - 算法(Algorithm),是用来操作容器中的数据的模板函数。例如,STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象,函数本身与他们操作的数据的结构和类型无关,因此他们可以在从简单数组到高度复杂容器的任何数据结构上使用;
string容器
用字符数组存放字符串容易数组越界且难以察觉。因此,C++ 标准模板库设计了 string 数据类型,专门用于字符串处理。
要使用 string 对象,须包含头文件 。
在用 C++ 编程时,要优先考虑用 string 对象来处理字符串,因为其用法比字符数组更简单,而且不容易出错。
初始化
string对象的初始化和普通类型变量的初始化基本相同,只是string作为类,还有类的一些特性(使用构造函数初始化),所以初始化方式有很多,如下(7):
string s1; //默认初始化
string s2(s1); //s2是s1的副本(复制过去)
string s3 = s1; //相当于s3(s1),s3是s1的副本
string s4("hello"); //初始化自定义内容
string s5 = "hello"; //等价于上行代码
string s6(1, 'a'); //s6由连续n(此时为1)个字符a组成的字符串
//生成一个临时的string再用临时的string类初始化
string s7 = string("hello");
string s8(string("hello"));
输入输出
== cin遇到空格就终止导致弱输入内容如“hello Amy”,只能读取空格前的内容“hello’。
== getline读取整行,如读取字符串s1: getline(cin,s1);
比较大小
string可以直接使用 > ,< ,== 等进行比较(按照ASCLL码的大小进行比较多,先比较首个字符,依次往后。若第一个字符不一样,以第一个的比较就能得出比较结果,若相同就继续比下一位,比出结果后就不用再看后面的内容了。)
string s9 = "akl", s10 = "abo";
int main() {
if (s9 > s10) {
cout << "s9>s10" << endl;
}
else if (s9 < s10) {
cout << "s9<s10" << endl;
}
else cout << "s9==s10" << endl;
return 0;
}
链接
string可以使用== +==来直接链接:
string s9 = "akl", s10 = "abo";
string s11 = s9 + s10;
int main() {
cout << "s9+s10=" <<s11<< endl;
return 0;
}
获取字符
- .使用C++11新特性的for
int main() {
string s1 = "aaacccvvv";
for (auto c : s1) {
cout << c <<" ";
}
return 0;
}
- 使用运算符[]+size()函数
int main() {
string s1 = "aaacccvvv";
for (int i = 0; i < s1.size();i++) {
cout << s1[i] <<" ";
}
return 0;
}
- 使用迭代器
int main() {
string s1 = "hello word";
for (auto i = s1.begin(); i != s1.end();i++) {
cout << *i <<" ";
}
return 0;
}
拷贝对象
string s(s1,pos); //拷贝s1从下标pos到结尾的内容;
string s(s1,pos,len); //拷贝s1从下标pos开始的len个字符(往后数)。
pos>s1.size()时为未定义行为;
pos=s1.size()时拷贝一个空字符(因为后面没内容)。

未定义行为或空字符都不输出内容。
int main() {
string s1 = "value";
string s2(s1, 1); //拷贝s1的下标1及之后内容
cout << "s2=" << s2 << endl;
string s3(s1, 2, 4); //拷贝s1从下标2及之后连续4个字符
cout << "s3=" << s3 << endl;
string s4(s1, 1, 8); //对应位置上没内容就不拷贝
cout << "s4=" << s4 << endl;
string s5(s1, 5, 9); //pos=size时为空字符
cout <<"s5="<< s5 << endl;
return 0;
}
substr函数
s.substr(pos,n);
返回一个string对象,返回的对象包含s从pos下标开始的n个字符。pos和n均为可选参数。
pos默认为下标0;n默认为s.size()-pos
int main() {
string s("value");
string s1 = s.substr(); //默认pos=0,n=s.size()-pos
string s2 = s.substr(2); //仅输入一个数默认为pos,且n=s.size()-pos
string s3 = s.substr(1, 3); //pos=1,n=3
string s4 = s.substr(1, 7); //s4为"alue",大小为4,多余位为空
string s5 = s.substr(7, 8); //pos>size时报错
cout << s1 << " " << s2 << " " << s3 << " "<<s4;
return 0;
}
insert函数
- iterator insert( iterator pos, CharT ch ) //在位置pos上加上‘ch’
- void insert( iterator pos, size_type count, CharT ch ) //在pos上加count个’ch’
- void insert( iterator pos, InputIt first, InputIt last ) //在pos上加 [s.begin(), ++s.begin()) 的内容
- 插入初始化列表
int main() {
string s("value");
s.insert(s.begin(),'s'); //执行结果“svalue”
s.insert(s.begin(),1,'s'); //执行结果“ssvalue”
s.insert(s.end(), { '1','2' });//执行结果“ssvalue12”
s.insert(s.begin(), s.begin(), ++s.begin());
cout << s << endl; //执行结果“sssvalue12”
return 0;
}
3中加的内容范围为 [s.begin(), ++s.begin()) :
包含:第一个字符 ‘s’
不包含:第二个字符 ‘s’
所以实际上只插入了一个字符 ‘s’
erase函数
basic_string & erase(size_type pos=0, size_type n=npos)
删除s从pos下标开始的n个字符,并返回删除后的s。当pos > s.size()时报错。
iterator erase(const_iterator position)
删除s迭代器position位置的字符,并返回下一个字符的迭代器。
iterator erase(const_iterator first, const_iterator last)
删除s迭代器[first,last)区间的字符,并返回last字符的迭代器
int main() {
string s("value");
string s1("value");
string s2("value");
string s3("value");
s.erase(0, 2); //lue
s1.erase(s1.begin()); //alue
s2.erase(); //为空
s3.erase(s3.begin(), ++s3.begin());
//删除从 begin() 到 ++begin() 范围内的字符,范围是左闭右开的
//所以只删除了‘v’,输出"alue"
cout << s<<" " << s1<<" " << s2 <<" " << s3;
return 0;
}
append函数
append是在string对象的末尾进行插入操作。这一点使用+运算符也能实现。
int main() {
string s("value");
s.append("value"); //执行完s="valuevalue";
cout << s;
return 0;
}
replace函数
int main() {
string s = "i very love China!";
const char* cp1 = "truly";
const char* cp2 = "truly!!!";
string str1 = "really";
//从s下标2开始删除4个元素后在下标2位置上插入cp1
s.replace(2, 4, cp1);
cout << s << endl; //输出 "i truly love China!"
//从s下标2开始删除5个元素后在下标2位置上插入cp2的前5个字符
s.replace(2, 5, cp2, 5);
cout << s << endl; //输出 "i truly love China!"
//从s下标2开始删除5个元素后在下标2位置上插入str1的下标0开始的6个字符
s.replace(2, 5, str1, 0, 6);
cout << s << endl; //输出"i really love China!"
//从s下标2开始删除6个元素后在下标2位置上插入4个‘*’
s.replace(2, 6, 4, '*');
cout << s << endl; //输出"i **** love China!"
return 0;
}
练习
输入一串带有标点符号的字符串,去除字符串中的标点符号。
判断字符是否是标点符号用ispunct();
int main() {
string s;
cin >> s;
//auto:自动类型推断,让编译器自动推断变量类型
//each:循环变量名,在每次迭代中代表字符串中的一个字符
for (auto each : s) {
if (!ispunct(each)) { //判断不是符号时输出
cout << each;
}
}
return 0;
}
更多推荐
所有评论(0)