一、标准库中的string类
1.1 string类
1. string是表示字符串的字符串类
2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
4. 不能操作多字节或者变长字符的序列。
5.在使用string类时,必须包含#include头文件以及using namespace std。
1.2 string类的常用接口
1、string类对象的常见构造
(constructor)函数名称 功能说明 string() 构造空的string类对象,即空字符串 string(const char* s) 用C-string来构造string对象 string(size_t n , char c) string类对象中包含n个字符c string(const string&s) 拷贝构造函数 例:
int main() { string s1; string s2("hello"); string s3(s2); //string s3 = s2; string s4(10, 'a'); cin >> s1; cout << s1 << endl; cout << s2 << endl; cout << s3 << endl; cout << s4 << endl; return 0; }
2、string类对象的访问及遍历操作
函数名称 功能说明 operator[ ] 返回pos位置的字符,const string类对象调用 begin+end begin获取一个字符的迭代器+end获取最后一个字符下一个位置的迭代器
rbegin+rend rbegin获取最后一个字符的迭代器+rend获取一个字符前一个位置的迭代器 范围for C++11支持更简洁的范围for的新遍历方式 例1:
int main()//[]的使用 { string s1("hello world"); string s2 = "hello world"; // 遍历string for (size_t i = 0; i < s1.size(); i++) { // 读 cout << s1[i] << " "; } cout << endl; for (size_t i = 0; i < s1.size(); i++) { // 写 s1[i]++; } cout << s1 << endl; }
例2:
int main() { string s1("hello world"); string::iterator it = s1.begin(); //while (it < s1.end()) // 这里可以但是不建议 while (it != s1.end()) // 推荐,通用 { // 读 cout << *it << " "; ++it; } cout << endl; //string::reverse_iterator rit = s1.rbegin(); auto rit = s1.rbegin(); while (rit != s1.rend()) { cout << *rit << " "; ++rit; } cout << endl; // 读 for (auto ch : s1) { cout << ch << " "; } cout << endl; // 写 for (auto& ch : s1) { ch++; } cout << endl; cout << s1 << endl; return 0; }
3、string类对象的容量操作
函数名称 功能说明 size 返回字符串有效长度 length 返回字符串有效长度 capacity 返回空间总大小 clear 清空有效字符 reserve 为字符串预留空间 resize 将有效字符的个数改成n个,若n大于当前size则用指定字符填充,若未指定字符则会默认用 ' \0 ' 填充(插入);若n小于当前size则删除(size - n)个字符(删除) 例1:
int main() { string s1("hello world"); cout << s1.size() << endl; cout << s1.length() << endl; cout << s1.capacity() << endl; s1.clear(); s1 += "张三"; cout << s1.size() << endl; cout << s1.capacity() << endl;//clear()后空间不会被释放 return 0; }
例2:
int main() { string s; s.reserve(10); size_t old = s.capacity(); cout << "初始" << s.capacity() << endl; for (size_t i = 0; i < 100; i++) { s.push_back('x'); if (s.capacity() != old) { cout << "扩容:" << s.capacity() << endl; old = s.capacity(); } } cout << s.capacity() << endl; return 0; }
例3:
int main() { string s1("hello world"); cout << s1 << endl; cout << s1.size() << endl; cout << s1.capacity() << endl; //s1.resize(13); //s1.resize(13, 'x'); s1.resize(20, 'x'); cout << s1 << endl; cout << s1.size() << endl; cout << s1.capacity() << endl; s1.resize(5); cout << s1 << endl; cout << s1.size() << endl; cout << s1.capacity() << endl; string s2; s2.resize(10, '#'); cout << s2 << endl; cout << s2.size() << endl; cout << s2.capacity() << endl; return 0; }
4、类对象的修改操作
函数名称 功能说明 push_back 在字符串后尾插字符
append 在字符串后追加字符串 operator+= 在字符串后追加字符串 operator+(全局函数) 尽量少用,因为传值返回,导致深拷贝效率低 find 从字符串pos位置开始向后找字符,返回该字符在字符串中的位置下标 rfind 从字符串pos位置开始向前找字符,返回该字符在字符串中的位置下标 substr 在str中从pos位置开始,截取n个字符,然后将其返回 例1:
int main() { string ss("world"); string s; s.push_back('#'); s.append("hello"); s.append(ss); cout<<s<< endl; s += '#'; s += "hello"; s += ss; cout << s << endl; string ret1 = ss + '#'; string ret2 = ss + "hello"; cout << ret1 << endl; cout << ret2 << endl; return 0; }
例2:
int main() { string s1("test.cpp.tar.zip"); size_t j = s1.find('.'); size_t i = s1.rfind('.'); string s2 = s1.substr(i); cout << s2 << endl; s2 = s1.substr(j,4); cout << s2 << endl; return 0; }
例3:
int main() { string s3("https://legacy.cplusplus.com/reference/string/string/rfind/"); // 协议 // 域名 // 资源名 string sub1, sub2, sub3; size_t i1 = s3.find(':'); if (i1 != string::npos) sub1 = s3.substr(0, i1); else cout << "没有找到i1" << endl; size_t i2 = s3.find('/', i1 + 3); if (i2 != string::npos) sub2 = s3.substr(i1 + 3, i2 - (i1 + 3)); else cout << "没有找到i2" << endl; sub3 = s3.substr(i2 + 1); cout << sub1 << endl; cout << sub2 << endl; cout << sub3 << endl; return 0; }
待续……