STL学习笔记-- string
string 基本字符序列容器
C语言并没有提供一个专门的字符串类型,需要通过字符数组,对字符串进行存储和处理。字符数组的末尾是一个值为 0 的 null 字符,表示字符串的结束。从而,一个用于存储 n 个字符的字符数组,字符个数为 n+1 。基于这样的字符数组,就可实现字符串的字符添加、删除、搜索、替换、连接和子串操作等。
在标准 C++ 中,字符串类 string 由 C++ STL 实现,提供丰富的字符串的处理功能。string 是一个基于字符的序列容器,具有vector向量容器一样的内部线性结构,字符逐一写入容器,最后以 null 字符结束。虽然 vector<char> 的成员函数也具有一定的字符串操作性质,但是不及string 接口丰富,易于使用和扩充容器。
使用 string 基本字符序列容器,必须先通过宏语句 "#include <string>" 将 string 的实现代码包含进来,才可编译程序。
创建 string 对象
字符串的操作,需要先用 string 类型的构造函数,构造出一个 string 对象,为随后添加的字符分配内存,并初始化 string 对象的内部变量。如下是它的几个常用的构造函数原型。
1. string()
默认的构造函数,用于创建一个不包含任何非空字符的 string 对象。
例如,下面一行代码创建空的 string 对象 s .
string s;
2 string(const string& s, size_type pos = 0, size_type n=npos)
拷贝构造函数,将 string 对象 s 的 [pos, pos+n) 中的字符拷贝到新创建的 string 对象空间中,其中 string::npos 已定义为 -1。当 pos取值0,n取值 string::npos 时,就是用整个字符串 s 拷贝创建一个新的 string 对象。
例如,下面代码拷贝创建 string 对象 s2
// string s1;
string s2(s1);
3. string(const char*)
将 char* 数组的字符拷贝到新创建的 string 对象空间中。
例如,下面代码将字符数组 cArray 的3个字符,拷贝到 string 对象 s 中。
char* cArray="abc";
string s(cArray); // s 包含字符 'a', 'b', 'c' 和一个 null 字符
1 /* 字符的添加 2 string 对象具有如下几个常用的添加字符或字符串的函数,并提供了与这些添加函数相对应的更方便的字符串 "+" 和 "+=" 操作。 3 void push_back(char c) // 在 string 对象的字符串尾部添加一个【字符】 c 4 string& append(const char* s) // 在 string 对象的字符串尾部添加【字符串】 s 5 string& append(const string& s) // 在 string 对象的字符串尾部添加 s 对象的【字符串】 6 iterator insert(iterator pos, const char& c) // 在 string 对象的 pos 位置之前,插入一个字符 c 7 8 下面的示例程序创建 string 对象 str1 和 str2 ,然后使用上面的函数或操作,进行字符或字符串的添加操作。 9 */ 10 11 -------------------------------------------------------- 字符添加 12 #include <string> 13 #include <iostream> 14 using namespace std; 15 int main() 16 { 17 string str1("abcd"); 18 /* 19 VC6.0 版本的编译器的 STL 有点点老旧了。不支持string 下面的 push_back 操作, 20 在vs2010下面测试,string 里面,是支持 push_back操作的 21 */ 22 // str1.push_back('a'); 23 // str1.push_back('b'); 24 // str1.push_back('c'); 25 // str1.push_back('d'); 26 cout << "打印str1: "<< str1 << endl; 27 28 char* cArray = "efgh"; 29 string str2(cArray); 30 cout << "打印str2: " << str2 << endl; 31 32 // 字符串的 + 操作 33 cout << "打印str1+str2: " << str1+str2 << endl; 34 35 // 字符串 str1后添加字符串 str2 36 cout << "append后,打印 str1: " << str1.append(str2) << endl; 37 38 // 在 str1 的第2个字符位置前插入字符 '8' 39 string::iterator i; 40 i = str1.begin(); 41 i++; 42 str1.insert(i, '8'); 43 cout << "insert后,打印 str1: " << str1 << endl; 44 45 // 字符串的 "+=" 操作 46 str1 += str2; 47 cout << "str1+=str2 后,打印 str1: " << str1 << endl; 48 49 return 0; 50 }
1 /* 字符的遍历访问 2 string 字符串提供了数组操作符 “[]” ,用于访问指定索引位置处的字符。一般的字符遍历则是使用前向迭代器和反向迭代器来进行。此时,通常要用 begin/rbegin 和 end/rend 函数找出遍历开始的首字符和末字符,然后通过迭代器的 “++” 和 “*” 操作,读取字符串中的字符。 3 4 下面的示例程序,先用数组方式,将字符串的字符逐个打印出来。然后,用反向迭代器,将字符串逆序打印: 5 */ 6 7 -------------------------------------------------------- 字符的遍历 8 #include <string> 9 #include <iostream> 10 using namespace std; 11 int main() 12 { 13 char* cArray = "Hello, world!"; 14 string str(cArray); 15 // 数组方式 16 for (size_t j=0; j<str.size(); j++) 17 cout << "第" << j << "个字符:" << str[j] << endl; 18 19 // 迭代器方式 20 string::reverse_iterator ri, rend; 21 rend = str.rend(); 22 cout << "反向打印字符:" << endl; 23 for (ri=str.rbegin(); ri!=rend; ++ri) 24 cout << *ri << " "; 25 cout << endl; 26 27 return 0; 28 }
1 /* 字符的删除 2 字符串中字符的删除,可使用如下几个重载的 erase 和 clear 函数,分别删除指定位置上的若干字符或删除所有的字符。 3 iterator erase(iterator pos) // 删除字符串中 position 所指的字符 4 iterator erase(iterator first, iterator last) // 删除字符串中迭代器区间 [first, last) 上的所有字符 5 string& erase(size_type pos=0, size_type n=npos) // 删除字符串中从索引位置 pos 开始的 n个字符。 6 void clear() // 删除字符串中的所有字符 7 8 下面的程序给出了字符删除的示例: 9 */ 10 -------------------------------------------------------- 字符的删除 11 #include <string> 12 #include <iostream> 13 using namespace std; 14 int main() 15 { 16 char* cArray = "a12345678b"; 17 string str(cArray); 18 // 删除第一个字符 19 str.erase(str.begin()); 20 // 打印出 12345678b 21 cout << str << endl; 22 // 删除操作 23 str.erase(str.begin()+3, str.end()-2); 24 // 打印出 1238b 25 cout << str << endl; 26 27 // str.clear(); // 在VC6.0 下面又没有编译通过,VC6.0的 STL 有些老旧了 28 29 return 0; 30 }
1 /* 字符的替换 2 string 提供了相当多的字符替换的重载函数 replace ,可将指定索引位置或迭代器位置处的字符替换。如下是几个常用的函数原型说明: 3 string& replace(size_type pos, size_type n, const char* s) // 将当前字符串从 pos 索引位置开始的 n 个字符,替换为字符串 s 4 string& replace(size_type pos, size_type n, size_type n1, char c) // 将当前字符串从 pos 索引位置开始的 n 个字符,替换为 n1 个字符 c 5 string& replace(iterator first, iterator last, const char* s) // 将当前字符串的 [first, last) 区间中的字符替换为字符串 s 6 */ 7 8 -------------------------------------------------------- 字符的替换 9 #include <string> 10 #include <iostream> 11 using namespace std; 12 int main() 13 { 14 char* cArray = "hello,boy!"; 15 string str(cArray); 16 // boy 替换 girl 17 str.replace(6,3,"girl"); 18 // 打印 hello girl! 19 cout << str << endl; 20 21 // 将“!”替换为“。” 22 str.replace(10, 1, 1, '.'); 23 // 打印 hello girl. 24 cout << str << endl; 25 26 str.replace(str.begin(), str.begin()+5, "good morning"); 27 // 打印 good morning girl. 28 cout << str << endl; 29 30 return 0; 31 }
1 /* 字符的搜索 2 string 提供了如下几个比较常用的在字符串中搜索匹配的字符串或字符的函数 3 4 size_type find(const char* s, size_type pos=0) // 在当前字符串 pos 索引位置开始,查找子串 s ,返回找到的位置索引, -1 表示查找不到子串。 5 size_type find(char c, size_type pos=0) // 在当前字符串的 pos 索引位置开始,查找字符串 c 的索引位置,返回 -1 表示查找不到字符 c 6 7 size_type rfind(const char* s, size_type pos=npos) // 从当前字符串的 pos 索引位置开始,反向顺序查找子串 s ,返回找到字符串的索引位置, -1 表示查找不到该子串。 8 size_type rfind(char c, size_type pos=npos) // 从当前字符串的 pos 索引位置开始,查找位于子串 s 的字符,返回找到字符的索引位置, -1 表示查找不到该字符。 9 10 size_type find_first_of(const char* s, size_type pos=0) // 从当前字符串的 pos 索引位置开始,查找位于子串 s 的字符,返回找到字符的索引位置, -1 表示查找不到。 11 size_type find_first_not_of() //从当前字符串的 pos 索引位置开始,查找第1个不位于子串 s 的字符,返回找到字符的索引位置, -1 表示查找不到。 12 13 size_type find_last_of() // 从当前字符串的 pos 索引位置开始,查找最后一个子串 s 的字符,返回找到的字符的索引位置, -1 表示查找不到字符。 14 size_type find_last_not_of() // 从当前字符串的 pos 索引位置开始,查找最后一个不位于子串 s 的字符,返回找到的字符的索引位置, -1 表示查找不到字符。 15 16 下面的示例程序,使用了以上的函数进行字符串和字符的搜索 17 */ 18 19 -------------------------------------------------------- 字符的搜索 20 #include <string> 21 #include <iostream> 22 using namespace std; 23 int main() 24 { 25 string str("dog bird chicken bird cat"); 26 27 // 字符串查找 28 cout << str.find("bird") << endl; // 打印 4 29 cout << (int)str.find("pig") << endl; // 打印 -1 30 31 // 字符查找 32 cout << str.find('i', 7) << endl; // 打印 11 33 34 // 从字符串的 末尾 开始查找字符串 35 cout << str.rfind("bird") << endl; // 打印 17 36 37 // 从字符串的 末尾 开始查找字符 38 cout << str.rfind('i') << endl; // 打印 18 39 40 // 查找第1个属于某子串的字符 41 cout << str.find_first_of("13r98") << endl; // 找到字符 r, 打印 6 42 43 // 查找第1个不属于某字符串的字符 44 cout << str.find_first_not_of("dog bird 2009") << endl; // 找到字符 c , 打印 9 45 46 // 查找最后一个属于某子串的字符 47 cout << str.find_last_of("13r98") << endl; // 字符 r,打印19 48 49 // 查找最后一个不属于某字符串的字符 50 cout << str.find_last_not_of("tea") << endl; // 字符 c, 打印 22 51 52 53 return 0; 54 }
1 /* 字符串的比较 2 string 提供了字典式的比较函数 compare ,它的几个常用函数原型如下: 3 int compare(const string& s) // 将当前字符串与字符串 s 比较,相等返回 0 ,大于 s 返回 1 ,小于 s 返回 -1 4 int compare(size_type pos, size_type n, const string& s) // 将当前字符串从 pos 索引位置开始的 n 个字符构成的字符串与字符串 s 比较,相等返回 0 ,大于 s 返回 1 ,小于 s 返回 -1 5 int compare(const char* s) // 直接将当前字符串与字符串 s 比较。相等返回 0 ,大于 s 返回 1 ,小于 s 返回 -1 6 7 下面的示例程序使用 compare 函数,比较并打印字符串比较结果 8 */ 9 -------------------------------------------------------- 字符串的比较 10 #include <string> 11 #include <iostream> 12 using namespace std; 13 int main() 14 { 15 string str1("abcdef"); 16 string str2("abc"); 17 // 相等,打印0 18 cout << str1.compare("abcdef") << endl; 19 20 // str1 > str2 , 打印 1 21 cout << str1.compare(str2) << endl; 22 23 // str1 < "abyz" , 打印 -1 24 cout << str1.compare("abyz") << endl; 25 26 // str1 的前3个字符 == str2 , 打印 0 27 cout << str1.compare(0, 3, str2) << endl; 28 29 30 return 0; 31 }
1 /* 其他常用函数 2 string 字符串还有以下几个比较常用的函数,如下是他们的使用原型说明。 3 4 size_type length() // 字符串的非空字符个数,即字符串的长度 5 size_type size() // 返回字符串的长度 6 bool empty() // 字符串是否为空,空则返回 1,否则返回 0 7 const char* c_str() // 将string 对象转换为 c 字符数组。 (***) 8 */ 9 10 -------------------------------------------------------- string 的其他常用函数用法 11 #include <string> 12 #include <iostream> 13 using namespace std; 14 int main() 15 { 16 string str; 17 // 空字符串,返回 1 18 cout << str.empty() << endl; 19 str += "1234567"; 20 cout << str.empty() << endl; // 不为空,返回0 21 cout << str.size() << endl; // 7个字符,返回7 22 cout << str.length() << endl; // 返回 7 23 24 // 转换为字符数组 cArray 25 const char* cArray=str.c_str(); 26 // 返回字符 3 27 cout << cArray[2] << endl; 28 29 return 0; 30 }
// 补充几个其他的用法: 数组方式访问,或者.at() 函数方式访问。 #include <string> #include <iostream> using namespace std; int main() { string s1 = "abcdefghijklmnopqrst"; char chA = s1[3]; // 将第4个字符赋给chA,chA值为d char chB = s1.at(5); // 将第5个字符赋给chB,chB值为f char chC = s1[50]; // 数组越界 // char chD = s1.at(50); // 产生out_of_rang 异常,可以用try,catch捕获异常 cout << s1.c_str() << endl; // 输出字符串 s1 return 0; } string 的赋值 string &operator=(const string &s);//把字符串s赋给当前的字符串 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的子串 string substr(int pos=0, int n=npos) const; //返回由pos开始的n个字符组成的子字符串 string 的 assing 用法: // 自己去用代码实现,熟悉其含义和用法 string strA("到此一游"); string strC; strC = strA; strC.assign("abcdefghijk"); strC.assign("baidu"); strC.assign(strA); strC.assign(5,'f'); string与wstring的区别(*****) string是对char*的管理,一个字符占一个字节大小,一个汉字占两个字节,ASCII编码。 wstring是对wchar_t*的管理,一个字符占两个字节大小,一个汉字占两个字节,Unicode编码。 wstring的使用方法跟string类似,区别主要在于函数参数char*与函数参数wchar_t* 更多关于 string 与 wstring 的知识,这里不做讨论,因为,我也不清楚这方面的知识了。
-------------------------- string 小结
string 是一个字符序列容器,可自动管理字符的内存分配。教之传统的 char* 字符数组, string 提供了十分丰富函数用于字符的添加、删除、替换、查找和比较等。由于篇幅有限,相当多的函数并未列出,读者可参考 C++STL 的帮助文档。
string 缺点:在查找方面,string没有set、map快。这是他的一个缺点。
string 优点:字符串操作方面,是他的强项。。。。
============当你们看到这里的时候,我想说,你们有福了。
我有个《葵花宝典》和你们分享: http://vdisk.weibo.com/s===================