STL常用容器--string容器
1 string容器基本概念
C风格字符串(以空字符结尾的字符数组)太过复杂难于掌握,不适合大程序的开发,所以C++标准库定义了一种string类,定义在头文件<string>。
String和c风格字符串对比:
-
Char是一个指针,String是一个类
string封装了char,管理这个字符串,是一个char*型的容器。 -
String封装了很多实用的成员方法
查找find,拷贝copy,删除delete 替换replace,插入insert -
不用考虑内存释放和越界
string管理char*所分配的内存。每一次string的复制,取值都由string类负责维护,不用担心复制越界和取值越界等。
2 string容器常用操作
2.1 string 构造函数
string(); //创建一个空的字符串 例如: string str;
string(const string& str); //使用一个string对象初始化另一个string对象,例如: string s; string s1(s);
string(const char* s); //使用字符串s初始化,例如: const char *s = "123"; string str(s);
string(int n, char c); //使用n个字符c初始化,例如: string s(5, 'c');
/*
* string 构造函数
*/
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
string s1(s);
const char *str = "123";
string s2(str);
string s3(4, 'a');
cout << "s= " << s << endl;
cout << "s1= " << s1 << endl;
cout << "s2= " << s2 << endl;
cout << "s3= " << s3 << endl;
return 0;
}
2.2 string基本赋值操作
string& operator=(const char* s); //char*类型字符串 赋值给当前的字符串
string& operator=(const string &s); //把字符串s赋给当前的字符串
string& operator=(char c); //字符赋值给当前的字符串
string& assign(const char *s); //把字符串s赋给当前的字符串
string& assign(const char *s, int n); //把字符串s的前n个字符赋给当前的字符串
string& assign(const string &s); //把字符串s赋给当前字符串
string& assign(int n, char c); //用n个字符c赋给当前字符串
string& assign(const string &s, int start, int n); //将s从start开始n个字符赋值给字符串
/*
* string 基本赋值操作
*/
#include <iostream>
#include <string>
using namespace std;
int main()
{
const char *str = "123";
const string s = "abcef";
char c = 'A';
string s1;
#if 1
s1 = str;
cout << s1 << endl;
s1 = s;
cout << s1 << endl;
s1 = c;
cout << s1 << endl;
#endif
#if 1
s1.assign(str);
cout << s1 << endl;
s1.assign(str, 2);
cout << s1 << endl;
s1.assign(s);
cout << s1 << endl;
s1.assign(4, c);
cout << s1 << endl;
s1.assign(s, 0, 3);
cout << s1 << endl;
#endif
return 0;
}
2.3 string存取字符操作
char& operator[](int n); //通过[]方式取字符
char& at(int n); //通过at方法获取字符
// []和at的区别: []越界访问不会抛出异常,at()越界访问会抛出异常
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;
int main()
{
string str = "hello world";
for (int ii = 0; ii < str.size(); ++ii)
{
//cout << str[ii] << " ";
cout << str.at(ii) << " ";
}
cout << endl;
try
{
//cout << str[100] << endl;
cout << str.at(100) << endl;
}
catch(out_of_range &e)
{
cout << e.what() << endl;
}
catch(...)
{
cout << "其他异常" << endl;
}
return 0;
}
2.4 string拼接操作
string& operator+=(string& str); //重载+=操作符
string& operator+=(char* str); //重载+=操作符
string& operator+=(char c); //重载+=操作符
string& append(char *s); //把字符串s连接到当前字符串结尾
string& append(char *s, int n); //把字符串s的前n个字符连接到当前字符串结尾
string& append(string &s); //同operator+=()
string& append(string &s, int pos, int n); //把字符串s中从pos开始的n个字符连接到当前字符串结尾
string& append(int n, char c); //在当前字符串结尾添加n个字符c
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1 = "abc";
string s2 = "123";
char *str = const_cast<char*>("456");
char c = 'z';
string s3;
#if 1
s3 = s1+s2;
cout << s3 << endl;
s3 = s1+str;
cout << s3 << endl;
s3 = s1+c;
cout << s3 << endl;
#endif
#if 1
s3 = s2.append(str);
cout << s3 << endl;
s3 = s2.append(str, 2);
cout << s3 << endl;
s3 = s2.append(s1);
cout << s3 << endl;
s3 = s2.append(s1, 0, 1);
cout << s3 << endl;
s3 = s2.append(4, c);
cout << s3 << endl;
#endif
return 0;
2.5 string查找和替换
//未找到返回-1
int find(string& str, int pos = 0) const; //查找str第一次出现位置,从pos开始查找
int find(char* s, int pos = 0) const; //查找s第一次出现位置,从pos开始查找
int find(char* s, int pos, int n) const; //从pos位置查找s的前n个字符第一次位置
int find(char c, int pos = 0) const; //查找字符c第一次出现位置
int rfind(string& str, int pos = npos) const; //查找str最后一次位置,从pos开始查找
int rfind(char* s, int pos = npos) const; //查找s最后一次出现位置,从pos开始查找
int rfind(char* s, int pos, int n) const; //从pos查找s的前n个字符最后一次位置
int rfind(char c, int pos = 0) const; //查找字符c最后一次出现位置
string& replace(int pos, int n, string& str); //替换从pos开始n个字符为字符串str
string& replace(int pos, int n, char* s); //替换从pos开始的n个字符为字符串s
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "hello world";
char *str = const_cast<char*>("l");
int ret = 0;
ret = s.find(str);
cout << ret << endl;
ret = s.find(str, 5);
cout << ret << endl;
ret = s.rfind(str);
cout << ret << endl;
string s1 = "hi";
cout << s << endl;
s.replace(0, 5, s1);
cout << s << endl;
return 0;
}
2.6 string比较操作
/*
compare函数在>时返回大于0的数,<时返回小于0的数,==时返回 0。
比较区分大小写,比较时参考字典顺序,排越前面的越小。
大写的A比小写的a小。
*/
int compare(string &s) const;//与字符串s比较
int compare(char *s) const;//与字符串s比较
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1 = "aa";
string s2 = "ab";
char *s3 = const_cast<char*>("aa");
string s4 = "A";
//s4 < s1 == s3 < s2
int ret = s1.compare(s2);
cout << ret << endl;
ret = s1.compare(s3);
cout << ret << endl;
ret = s1.compare(s4);
cout << ret << endl;
return 0;
}
2.7 string子串
string substr(int pos = 0, int n = npos) const; //返回由pos开始的n个字符组成的字符串
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "hello world";
string s1;
s1 = s.substr(1, 4);
cout << s1 << endl;
return 0;
}
2.8 string插入和删除操作
string& insert(int pos, char* s); //在pos位置前插入字符串s
string& insert(int pos, string& str); //在pos位置前插入字符串str
string& insert(int pos, int n, char c); //在指定位置插入n个字符c
string& erase(int pos, int n = npos); //删除从Pos开始的n个字符
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "hello world";
string s1 = "abc";
char *str = const_cast<char*>("efg");
cout << s << endl;
s.insert(1, s1);
cout << s << endl;
s = "hello world";
cout << s << endl;
s.insert(1, str);
cout << s << endl;
s = "hello world";
cout << s << endl;
s.insert(1, 2, 'a');
cout << s << endl;
s = "hello world";
cout << s << endl;
s.erase(1, 2);
cout << s << endl;
return 0;
}
2.9 string和c-style字符串转换
//string 转 char*
string str = "hello world";
const char *cstr = str.c_str();
//char* 转 string
char *cs = const_cast<char*>("hello world");
string s(cs);
注意1
在c++中存在一个从const char*到string的隐式类型转换,却不存在从一个string对象到C_string的自动类型转换。对于string类型的字符串,可以通过c_str()函数返回string对象对应的C_string.
通常,程序员在整个程序中应坚持使用string类对象,直到必须将内容转化为char*时才将其转换为C_string.
注意2
为了修改string字符串的内容,下标操作符[]和at都会返回字符的引用。但当字符串的内存被重新分配之后,可能发生错误.
3 案例
3.1 大小写转换
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "abcdEFGh!";
cout << s << endl;
// 小写转大写
for (auto &i : s)
{
i = toupper(i);
}
cout << s << endl;
// 大写转小写
for (auto &i : s)
{
i = tolower(i);
}
cout << s << endl;
return 0;
3.2 解析字符串
将网站www.baidu.com中每段存放在vector容器中
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string s = "www.baidu.com";
string str;
vector<string> v;
int start = 0;
int pos = -1;
while (true)
{
pos = s.find(".", start); // 找到第一个.的位置
if (-1 == pos) // 将com存入vector容器中
{
str = s.substr(start, s.size() - start);
v.push_back(str);
break;
}
str = s.substr(start, pos - start); // 找字串
v.push_back(str); // 压入容器
start = pos + 1;
}
// 打印方式一
for (auto i : v)
{
cout << i << endl;
}
/*
* 打印方式二
for (vector<string>::iterator it = v.begin(); it != v.end(); ++it)
{
cout << *it << endl;
}
*/
return 0;
}