C++ string
函数名称 | 功能 |
---|---|
构造函数 | 产生或复制字符串 |
析构函数 | 销毁字符串 |
=,assign | 赋以新值 |
swap | 交换两个字符串的内容 |
+=,append(),push_back() | 添加字符 |
insert() | 插入字符 |
erase() | 删除字符 |
clear() | 移除全部字符 |
resize() | 改变字符数量 |
replace() | 替换字符 |
+ | 串联字符串 |
==,! =,<,<=,>,>=,compare() | 比较字符串内容 |
size(),length() | 返回字符数量 |
max_size() | 返回字符的最大可能个数 |
empty() | 判断字符串是否为空 |
capacity() | 返回重新分配之前的字符容量 |
reserve() | 保留内存以存储一定数量的字符 |
[],at() | 存取单一字符 |
>>,getline() | 从 stream 中读取某值 |
<< | 将值写入 stream |
copy() | 将内容复制为一个 C - string |
c_str() | 将内容以 C - string 形式返回 |
data() | 将内容以字符数组形式返回 |
substr() | 返回子字符串 |
find() | 搜寻某子字符串或字符 |
begin( ),end() | 提供正向迭代器支持 |
rbegin(),rend() | 提供逆向迭代器支持 |
get_allocator() | 返回配置器 |
构造函数
初始化一个 string 类,可以使用C风格字符串或string类型对象,也可以使用C风格字符串的部分或string类型对象的部分或序列。
注意,不能使用字符或者整数去初始化字符串。
常见的 string 类构造函数有以下几种形式:
string strs //生成空字符串
string s(str) //生成字符串str的复制品
string s(str, stridx) //将字符串str中始于stridx的部分作为构造函数的初值
/*
string strs("hello");
string s(strs, 2); // llo
*/
string s(str, strbegin, strlen) //将字符串str中始于strbegin、长度为strlen的部分作为字符串初值
string s(cstr) //以C_string类型cstr作为字符串s的初值
string s(cstr,char_len) //以C_string类型cstr的前char_len个字符串作为字符串s的初值
string s(num, c) //生成一个字符串,包含num个c字符
string s(strs, beg, end) //以区间[beg, end]内的字符作为字符串s的初值
如果字符串只包含一个字符,使用构造函数对其初始化时,使用以下两种形式比较合理:
std::string s('x'); //错误
std::string s(1, 'x'); //正确
std::string s("x"); //正确
C_string 一般被认为是常规的 C++ 字符串。目前,在 C++ 中确实存在一个从 const char * 到 string 的隐式型别转换,却不存在从 string 对象到 C_string 的自动型别转换。对于 string 类型的字符串,可以通过 c_str() 函数返回该 string 类对象对应的 C_string。
通常,程序员在整个程序中应坚持使用 string 类对象,直到必须将内容转化为 char* 时才将其转换为 C_string。
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str ("12345678");
char ch[ ] = "abcdefgh";
string a; //定义一个空字符串
string str_1 (str); //构造函数,全部复制
string str_2 (str, 2, 5); //构造函数,从字符串str的第2个元素开始,复制5个元素,赋值给str_2
string str_3 (ch, 5); //将字符串ch的前5个元素赋值给str_3
string str_4 (5,'X'); //将 5 个 'X' 组成的字符串 "XXXXX" 赋值给 str_4
string str_5 (str.begin(), str.end()); //复制字符串 str 的所有元素,并赋值给 str_5
cout << str << endl;
cout << a << endl ;
cout << str_1 << endl;
cout << str_2 << endl;
cout << str_3 << endl;
cout << str_4 << endl;
cout << str_5 << endl;
return 0;
}
// 结果:
// 12345678
// 12345678
// 34567
// abcde
// XXXXX
// 12345678
析构函数
【原型】:
~string() //销毁所有内存,释放内存
【作用】:
析构函数于构造函数相对应,构造函数是对象创建的时候自动调用的,而析构函数就是对象在销毁的时候自动调用的的
【特点】:
1)构造函数可以有多个来构成重载,但析构函数只能有一个,不能构成重载
2)构造函数可以有参数,但析构函数不能有参数
3)与构造函数相同的是,如果我们没有显式的写出析构函数,那么编译器也会自动的给我们加上一个析构函数,什么都不做;如果我们显式的写了析构函数,那么将会覆盖默认的析构函数
4)在主函数中,析构函数的执行在return语句之前,这也说明主函数结束的标志是return,return执行完后主函数也就执行完了,就算return后面还有其他的语句,也不会执行的
5)与栈区普通对象不同,堆区指针对象并不会自己主动执行析构函数,就算运行到主函数结束,指针对象的析构函数也不会被执行,只有使用delete才会触发析构函数
6)当我们在类中声明了一些指针变量时,我们一般就在析构函数中进行释放空间,因为系统并不会释放指针变量指向的空间,我们需要自己来delete,而一般这个delete就放在析构函数里面
7)malloc不会触发构造函数,但new可以。。free不会触发析构函数,但delete可以
=,assign
1.两者性能差不多, equally fast
2.assign用法多, operator=意思清晰
string &operator=(const string &s); // 把字符串s赋给当前字符串
string &assign(const char *s); // 用c类型字符串s赋值
string &assign(const char *s,int n); // 用c字符串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 &assign(const_iterator first,const_itertor last); // 把first和last迭代器之间的部分赋给字符串
【实例】
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str ("12345678");
char ch[ ] = "abcdefgh";
string a; //定义一个空字符串
string str_1, str_2, str_3, str_4, str_5;
str_1.assign(str); //构造函数,全部复制
str_2.assign(str, 2, 5); //构造函数,从字符串str的第2个元素开始,复制5个元素,赋值给str_2
str_3.assign(ch, 5); //将字符串ch的前5个元素赋值给str_3
str_4.assign(5,'X'); //将 5 个 'X' 组成的字符串 "XXXXX" 赋值给 str_4
str_5.assign(str.begin(), str.end()); //复制字符串 str 的所有元素,并赋值给 str_5
cout << str << endl;
cout << a << endl ;
cout << str_1 << endl;
cout << str_2 << endl;
cout << str_3 << endl;
cout << str_4 << endl;
cout << str_5 << endl;
return 0;
}
// 12345678
// 12345678
// 34567
// abcde
// XXXXX
// 12345678
swap
交换两个字符串
// swap strings
#include <iostream>
#include <string>
int main ()
{
std::string buyer ("money");
std::string seller ("goods");
std::cout << "Before the swap, buyer has " << buyer;
std::cout << " and seller has " << seller << '\n';
seller.swap (buyer);
std::cout << " After the swap, buyer has " << buyer;
std::cout << " and seller has " << seller << '\n';
return 0;
}
// 结果
// Before the swap, buyer has money and seller has goods
// After the swap, buyer has goods and seller has money
+=,append(),push_back()
1. +=:
【原型1:】
string& operator+= (const string& str);
// 把string型字符串str连接到源字符串的结尾。
【原型2:】
string& operator+= (const char* s);
// 把char型字符串s连接到源字符串的结尾。
【原型3:】
string& operator+= (char c);
// 把字符c连接到源字符串的结尾。
【实例:】
#include<iostream>
#include<string>
int main()
{
std::string my_str = "holiday";
my_str += "!";
char * cStr = " happy";
char chr = '!';
my_str += cStr;
my_str += chr;
std::cout << my_str << std::endl; // holiday!
return 0;
}
2. append():
【原型1:】
string& append (const string& str);
// 把string型字符串str连接到源字符串结尾。
【原型2:】
string& append (const string& str, size_t subpos, size_t sublen = npos);
// 用string型字符串str中从下标为subpos处开始的sublen长度的字符串连接到当前字符串结尾。
【原型3:】
string& append (const char* s);
// 把char型字符串s连接到当前字符串结尾。
【原型4:】
string& append (const char* s, size_t n);
// 用char型字符串s开始的n个字符连接到当前字符串结尾。
【原型5:】
string& append(size_t n, char c);
// 在当前字符串结尾添加n个字符c。
【原型6:】
template < class InputIterator> string& append(InputIterator first, InputIterator last);
// Appends a copy of the seq
【实例:】
#include <iostream>
using namespace std;
int main()
{
string str1a ( "Hello " );
string str2a ( "World!" );
str1a.append (str2a);
cout << "str1a : " << str1a << endl;
string str1b ( "Hello " );
string str2b = "World!";
str1b.append (str2b , 3, 2);
cout << "str1b : " << str1b << endl;
string str1c ( "Hello " );
char * str2c = "World!";
str1c.append (str2c);
cout << "str1c : " << str1c << endl;
string str1d ( "Hello " );
str1d.append (str2c, 3);
cout << "str1d : " << str1d << endl;
string str1e ( "Hello " );
str1e.append ( 4 , '!' );
cout << "str1e : " << str1e << endl;
string str1f ( "Hello " ), str2f ( "Wide World " );
str1f.append ( str2f.begin ( ) + 5 , str2f.end ( ) - 1 );
cout << "str1f : " << str1f << endl;
return 0;
}
// 结果:
// str1a : Hello World!
// str1b : Hello ld
// str1c : Hello World!
// str1d : Hello Wor
// str1e : Hello !!!!
// str1f : Hello World
3. push_back():将元素添加到该字符串的末尾
my_str.push_back("123");//错误
my_str.push_back(‘1‘);//ok
insert()
参考
https://www.cnblogs.com/meihao1203/p/9670680.html
erase()
string& erase (size_t pos = 0, size_t len = npos);
iterator erase (iterator p);
iterator erase (iterator first, iterator last);
【实例】
// string::erase
#include <iostream>
#include <string>
int main ()
{
std::string str ("This is an example sentence.");
std::cout << str << '\n';
// "This is an example sentence."
str.erase (10,8); // ^^^^^^^^
std::cout << str << '\n';
// "This is an sentence."
str.erase (str.begin()+9); // ^
std::cout << str << '\n';
// "This is a sentence."
str.erase (str.begin()+5, str.end()-9); // ^^^^^
std::cout << str << '\n';
// "This sentence."
return 0;
}
clear()
【实例】
// string::clear
#include <iostream>
#include <string>
int main ()
{
char c;
std::string str = "hello!";
str.clear();
std::cout << str << std::endl;
return 0;
}
resize()
void resize (size_t n);
void resize (size_t n, char c);
【实例】
// resizing string
#include <iostream>
#include <string>
int main ()
{
std::string str ("I like to code in C");
std::cout << str << '\n';
unsigned sz = str.size();
str.resize (sz+2,'+');
std::cout << str << '\n';
str.resize (14);
std::cout << str << '\n';
return 0;
}
// 结果
// I like to code in C
// I like to code in C++
// I like to code
replace()
参照https://blog.csdn.net/weixin_39583140/article/details/88812044
1.应用一:
string &replace(size_t pos, size_t len, const &str) // 将源字符串的第pos位置开始的len个字符串用str替换
2.应用二:
string &replace(size_t pos, size_t len, const string &str, size_t subpos, size_t sublen) // 将源字符串的第pos位置开始的len个字符用str的subpos位置开始的sublen个字符替换
3.应用三:
string &replace(size_t pos, size_t len, const char* s) // 将源字符串的第pos位置开始的len个字符串用s替换
4.应用四:
string &replace(size_t pos,size_t len,const char* cch,size_t n)// 插入C串前n个字符
5.应用五:
string &replace(size_t pos,size_t len,size_t n,char c) // 将源字符串的第pos位置开始的len个字符串用n的字符c替换
6.应用六~应用九:(往后为迭代器操作)
string &replace(const_iterator it1, const_iterator it2, const string&str)
string &replace(const_iterator it1, const_iterator it2, const char* cch)
string &replace(const_iterator it1, const_iterator it2, const char* cch, size_t n)
string &replace(const_iterator it1, const_iterator it2, size_t n, char c)
【实例】
#include<iostream>
#include<string>
using namespace std;
int main() {
{//应用一:string &replace(size_t pos,size_t len,const &str)实现
string s = "0123456";
string str = "ABCD";
s.replace(2, 2, str);//在s的pos=2位置往后len=2字符(“23”)替换为"ABCD"
cout << s << "\n";
}
{//应用二:string &replace(size_t pos, size_tlen, const string &str, size_t subpos, size_t sublen)
//被替换位置(pos往后len长度),替换位置(subpos往后sublen长度)
string s = "0123456";
string str = "ABCD";
s.replace(2, 2, str, 1, 2);//s在s的pos=2位置往后len=2个字符(“23”)替换为“BC”(str中subpos=1往后两个位置)
cout << s << "\n";
}
{//应用三:string &replace(size_t pos,size_t len,const char* s) 插入C串
string s = "0123456";
char str[] = "ABCD";
s.replace(2, 2, str, 1, 2);////s在s的pos=2位置往后len=2个字符(“23”)替换为“BC”(str中subpos=1往后两个位置)
cout << s << "\n";
}
{//应用四:string &replace(size_t pos,size_t len,const char* cch,size_t n)插入C串前n个字符
string s = "0123456";
s.replace(2, 2, "ABCD", 2);//在指定位置(pos=2,len=2)插入“ABCD”前两个字符
cout << s << "\n";
}
{//应用五:string &replace(size_t pos, size_t len, size_t n, char c)
string s = "0123456";
s.replace(2, 2, 5, 'A');//在指定位置(pos=2,len=2)插入5个'A';
cout << s << "\n";
}
{//应用六:(只举一例,其他与size_t操作类似)
//string &replace(const_iterator first,const_iterator last,const string&str)
//string &replace(const_iterator first,const_iterator last,const char* cch)
//string &replace(const_iterator first,const_iterator last,const char* cch,size_t n)
//string &replace(const_iterator first,const_iterator last,size_t n,char c)
//需要注意的是迭代器操作中第二个参数不再是len而是位置
string s = "0123456";
string str = "ABCD";
string::iterator it= s.begin();
s.replace(it, it+2, str);//s在s的pos=2位置往后len=2个字符(“23”)替换为“BC”(str中subpos=1往后两个位置)
cout << s << "\n";
}
return 0;
}
// 结果:
// 01ABCD456
// 01BC456
// 01BC456
// 01AB456
// 01AAAAA456
// ABCD23456
+
string重载+运算符,用于串联两个字符串对象:
【实例】
#include<iostream>
#include<string>
int main()
{
std::string my_str = "holiday";
std::string my_str_add = "error" + "error";//错误
std::string my_str_add2 = my_str + "right";
std::string my_str_add3 = my_str + "right" + "right";
std::string my_str_add4 = "right" + my_str;
std::string my_str_add5 = "error" + "error" + my_str;//错误
return 0;
}
==,!=,<,<=,>,>=,compare()
Basic_string 类模板提供了>, <, ==, >=, <=, !=等比较运算符,还提供了compare()函数,其中compare()函数支持对参数处理,该函数返回一个整数来表示比较结果。如果相同,返回0,若字符串S1按字典顺序要先于S2,则返回负值;反之,则返回正值。
类 basic_string 的成员函数 compare() 的原型如下:
int compare (const basic_string& s) const;
int compare (const Ch* p) const;
int compare (size_type pos, size_type n, const basic_string& s) const;
int compare (size_type pos, size_type n, const basic_string& s,size_type pos2, size_type n2) const;
int compare (size_type pos, size_type n, const Ch* p, size_type = npos) const;
【实例】
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string A ("aBcdef");
string B ("AbcdEf");
string C ("123456");
string D ("123dfg");
//下面是各种比较方法
int m=A.compare (B); //完整的A和B的比较
int n=A.compare(1,5,B); //"Bcdef"和"AbcdEf"比较
int p=A.compare(1,5,B,4,2); //"Bcdef"和"Ef"比较
int q=C.compare(0,3,D,0,3); //"123"和"123"比较
cout << "m = " << m << ", n = " << n <<", p = " << p << ", q = " << q << endl;
cin.get();
return 0;
}
// m = 32, n = 1, p = -3, q = 0
【比较运算符实例:】
#include <iostream>
#include <string>
using namespace std;
void TrueOrFalse (int x)
{
cout << (x?"True":"False")<<endl;
}
int main ()
{
string S1 = "DEF";
string CP1 = "ABC";
string CP2 = "DEF";
string CP3 = "DEFG";
string CP4 ="def";
cout << "S1 = " << S1 << endl;
cout << "CP1 = " << CP1 <<endl;
cout << "CP2 = " << CP2 <<endl;
cout << "CP3 = " << CP3 <<endl;
cout << "CP4 = " << CP4 <<endl;
cout << "S1 == CP1 returned ";
TrueOrFalse (S1 == CP1);
cout << "S1 != CP2 returned ";
TrueOrFalse (S1 != CP2);
cout << "S1 < CP3 returned ";
TrueOrFalse (S1 < CP3);
cout << "CP1 <= S1 returned ";
TrueOrFalse (CP1 <= S1);
cout << "CP2 > S1 returned ";
TrueOrFalse (CP2 > S1);
cout << "CP4 >= S1 returned ";
TrueOrFalse (CP4 >= S1);
return 0;
}
// S1 = DEF
// CP1 = ABC
// CP2 = DEF
// CP3 = DEFG
// CP4 = def
// S1 == CP1 returned False
// S1 != CP2 returned False
// S1 < CP3 returned True
// CP1 <= S1 returned True
// CP2 > S1 returned False
// CP4 >= S1 returned True
empty(),size(),length(),capacity() and max_size(), reserve()
empty()
用来检验字符数是否为0,亦即字符串是否为空。应该优先使用该函数,因为它比length()或size()快。也就是说,使用if(s.empty() == true)而不使用if(s.size() == 0)
size()
函数返回字符串中现在拥有的字符数。
length()
函数返回字符串的长度
capacity()
返回已分配存储的大小。当前为字符串分配的存储空间的大小,以字节表示。 此容量不一定等于字符串长度。 它可以相等或更大,额外的空间允许对象在将新字符添加到字符串时优化其操作。
max_size()
返回字符串的最大大小,返回字符串可以达到的最大长度。
reserve()
为容器预留足够的空间,避免不必要的重复分配,分配空间大于等于函数的参数,影响capacity。
【实例】
// comparing size, length, capacity and max_size
#include <iostream>
#include <string>
int main ()
{
std::string str ("Test string");
std::cout << "size: " << str.size() << "\n";
std::cout << "length: " << str.length() << "\n";
std::cout << "capacity: " << str.capacity() << "\n";
std::cout << "max_size: " << str.max_size() << "\n";
str.reserve(30);
std::cout << "/***********/" << "\n";
std::cout << "size: " << str.size() << "\n";
std::cout << "length: " << str.length() << "\n";
std::cout << "capacity: " << str.capacity() << "\n";
std::cout << "max_size: " << str.max_size() << "\n";
return 0;
}
// size: 11
// length: 11
// capacity: 22
// max_size: 18446744073709551599
// /***********/
// size: 11
// length: 11
// capacity: 31
// max_size: 18446744073709551599
// 注意如果在字符串后面加上一个字符串结束标志\0, string s("Hello\0"),不影响它的长度和size
// reserve影响capacity大小,但capacity大小和reserve大小不一定一致
[],at()
可使用两种方法访问字符串中的单一字符:下标操作符[] 和成员函数at()。两者均返回指定的下标位置的字符。第 1 个字符索引(下标)为 0,最后的字符索引为 length()-1。
需要注意的是,这两种访问方法是有区别的:
- 下标操作符 [] 在使用时不检查索引的有效性,如果下标超出字符的长度范围,会示导致未定义行为。
- 函数 at() 在使用时会检查下标是否有效。如果给定的下标超出字符的长度范围,系统会抛出 out_of_range 异常。
【实例:】
#include <iostream>
#include <string>
int main()
{
std::string s ("abode");
std::cout << s << std::endl ;
std::cout << "使用[]访问s的第一个元素: " << s[0] << std::endl;
std::cout << "使用at()访问s的第一个元素: " << s.at(0) << std::endl;
return 0;
}
<<,>>,getline()
"<<" 和 ">>" 提供了C++语言的字符串输出和字符串输入功能。
"<<" : 可以将字符读入一个流中(例如ostream);
">>" : 可以实现将以空格或回车为"结束符" 的字符序列读入到对应的字符串中,并且开头和结尾的空白字符不包括进字符串中。
getline() 函数 :该函数的原型包括两种形式
template <class CharType, class Traits, class Allocator > basic_istream<CharType, Traits>& getline (basic_istream<CharType, Traits>& _Istr,basic_string <CharType,Traits, Allocator> &_Str);
//上述原型包含 2 个参数:第 1 个参数是输入流;第 2 个参数是保存输入内容的字符串
template <class CharType, class Traits, class Allocator> basic_istream<CharType, Traits>& getline (basic_istream <CharType, Traits>&_ Istr, basic_string <CharType, Traits, Allocator>& _Str,CharType_Delim);
//上述原型包含 3 个参数:第 1 个参数是输入流,第 2 个参数保存输入的字符串,第 3 个参数指定分界符。
注意:
该函数可将整行的所有字符读到字符串中。在读取字符时,遇到文件结束符、分界符、回车符时,将终止读入操作,且文件结束符、分界符、回车符在字符串中不会保存;当已读入的字符数目超过字符串所能容纳的最大字符数时,将会终止读入操作。
实例:
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string s1, s2;
getline(cin, s1);
getline(cin, s2, ' '); // 文件分界符是' '
cout << "You inputed chars are: " << s1 << endl;
cout << "You inputed chars are: " << s2 << endl;
return 0;
}
// I am a student
// I am a student
// You inputed chars are: I am a student
// You inputed chars are: I
copy()
原型:
size_t copy (char* s, size_t len, size_t pos = 0) const;
// str.copy(s, len, pos) 将str第pos个位置开始的len个字符复制到s中
实例:
// string::copy
#include <iostream>
#include <string>
int main ()
{
char buffer[20];
std::string str ("Test string...");
std::size_t length = str.copy(buffer,6,5);
buffer[length]='\0';
std::cout << "buffer contains: " << buffer << '\n';
return 0;
}
// buffer contains: string
c_str()
c_str():生成一个const char*指针,指向以空字符终止的数组。
注:
① c_str()得到的数组的数据是临时的,当源数据变化了,其中的数据就会失效。因此要么现用现转换,或把它的数据复制到用户自己可以管理的内存中。如下:
const char* c;
string s="1234";
c = s.c_str();
cout<<c<<endl; //输出:1234
s="abcd";
cout<<c<<endl; //输出:abcd
可以使用到strcpy等函数将数据复制到用户管理的内存中(推荐)。
char* c=new char[20];
string s="1234";
//c = s.c_str();
strcpy(c,s.c_str());
cout<<c<<endl; //输出:1234
s="abcd";
cout<<c<<endl; //输出:1234
② c_str()返回一个程序可读不可改的指向字符数组的指针,不需要手动释放或删除这个指针。
data()
与c_str()类似,但是返回的数组不以空字符终止。
substr()
原型:
string substr (size_t pos = 0, size_t len = npos) const;
// 返回源字符串从pos位置开始,len个长度的子串
实例:
// string::substr
#include <iostream>
#include <string>
int main ()
{
std::string str="We think in generalities, but we live in details.";
std::string str2 = str.substr (3,5); // think
std::cout << str2 << std::endl;
return 0;
}
find()
在 C/C++语言中,实现字符串查找功能的函数非常多。在 STL中,字符串的查找功能可以实现多种功能,比如说:
- 搜索单个字符、搜索子串;
- 实现前向搜索、后向搜索;
- 分别实现搜索第一个和最后一个满足条件的字符(或子串);
若查找 find() 函数和其他函数没有搜索到期望的字符(或子串),则返回 npos;若搜索成功,则返回搜索到的第 1 个字符或子串的位置。其中,npos 是一个无符号整数值,初始值为 -1。当搜索失败时, npos 表示“没有找到(not found)”或“所有剩余字符”。
所有查找 find() 函数的返回值均是 size_type 类型,即无符号整数类型。该返回值用于表明字符串中元素的个数或者字符在字符串中的位置。
下面分别介绍和字符查找相关的函数。
1. find()函数和 rfind():
size_type find (value_type _Chr, size_type _Off = 0) const;
// find()函数的第1个参数是被搜索的字符、第2个参数是在源串中开始搜索的下标位置
size_type find (const value_type* _Ptr , size_type _Off = 0) const;
// find()函数的第1个参数是被搜索的字符串,第2个参数是在源串中开始搜索的下标位置
size_type find (const value_type* _Ptr, size_type _Off = 0, size_type _Count) const;
// 第1个参数是被搜索的字符串,第2个参数是源串中开始搜索的下标,第3个参数是关于第1个参数的字符个数,可能是 _Ptr 的所有字符数,也可能是 _Ptr 的子串宇符个数
size_type find (const basic_string& _Str, size_type _Off = 0) const;
// 第1个参数是被搜索的字符串,第2参数是在源串中开始搜索的下标位置
rfind() 函数的原型和find()函数的原型类似,参数情况也类似。只不过 rfind() 函数适用于实现逆向查找。
【实例:】
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str_ch (" for");
string str (" Hi, Peter, I'm sick. Please bought some drugs for me.");
string::size_type m= str.find ('P', 5);
string::size_type rm= str.rfind('P', 5);
cout << "Example - find() : The position (forward) of 'P' is: " << (int) m << endl;
cout << "Example - rfind(): The position (reverse) of 'P' is: " << (int) rm << endl;
string::size_type n = str.find (" some", 0);
string::size_type rn = str.rfind (" some", 0);
cout << "Example - find () : The position (forward) of 'some' is: " << (int) n << endl;
cout << "Example - rfind () : The position (reverse) of 'some' is: " << (int) rn << endl;
string::size_type mo = str.find (" drugs", 0, 5);
string::size_type rmo = str.rfind (" drugs", 0, 5);
cout << "Example - find(): The position (forward) of 'drugs' is: " << (int) mo << endl;
cout << "Example - rfind(): The position (reverse) of 'drugs' is: " << (int) rmo << endl;
string::size_type no = str.find (str_ch, 0);
string::size_type rno = str.rfind(str_ch, 0);
cout << "Example - find (): The position of 'for' is: " << (int) no << endl;
cout << "Example - rfind(): The position of 'for' is: " << (int) rno << endl;
return 0;
}
// Example - find() : The position (forward) of 'P' is: 5
// Example - rfind(): The position (reverse) of 'P' is: 5
// Example - find () : The position (forward) of 'some' is: 35
// Example - rfind () : The position (reverse) of 'some' is: -1
// Example - find(): The position (forward) of 'drugs' is: 40
// Example - rfind(): The position (reverse) of 'drugs' is: -1
// Example - find (): The position of 'for' is: 46
// Example - rfind(): The position of 'for' is: -1
2. find_first_of()函数和 find_last_of()函数:
s.find_first_of(args) // 在s中查找args的任意字符的第一次出现
s.find_last_of(args) // 在s中查找args的任意字符的最后一次出现
3. find_first_not_of()函数和 find_last_not_of()函数:
s.find_first_not_of(args) // 在s中查找第一个不属于args的字符
s.find_last_not_of(args) // 在s中查找最后一个不属于args的字符
begin( ),end(),rbegin(),rend()
理解迭代器是理解STL的关键所在。模板使得算法独立于存储的数据类型,而迭代器使得算法独立于使用的容器类型。
参照
http://c.biancheng.net/view/1455.html
get_allocator()
参照
http://c.biancheng.net/view/1456.html
编写string类的构造函数、析构函数、赋值函数!!!!
//string.h
#ifndef STRING_H
#define STRING_H
#include <iostream>
#include <cstring>
namespace test {
class String
{
public:
String(const char *str = NULL); // 构造函数
~String(); // 析构函数
String(const String &str); //拷贝构造函数
String& operator = (const String &str); // =运算符重载,赋值函数
friend std::ostream & operator<<(std::ostream & os, const String & str);
private:
char *m_cStr; //用于保存字符串
};
}
// string.cpp
namespace test {
//普通构造函数
String::String(const char *str)
{
if (str == NULL) {
m_cStr = new char[1]; // 得分点:对空字符串自动申请存放结束标志'\0'的空
//加分点:对m_data加NULL 判断
*m_cStr = '\0';
} else {
int length = strlen(str);
m_cStr = new char[length+1];
strcpy(m_cStr, str);
}
}
// 析构函数
String::~String()
{
delete m_cStr;
}
//拷贝构造函数
String::String(const String &str) // 得分点:输入参数为const
{
int length = strlen(str.m_cStr);
m_cStr = new char[length + 1];
strcpy(m_cStr, str.m_cStr);
}
//赋值函数
String & String::operator =(const String &other) // 得分点:输入参数为const型
{
if (this == &other) { //得分点:检查自赋值
return *this;
}
delete [] m_cStr; //得分点:释放原有的内存资源
int length = strlen(other.m_cStr);
m_cStr = new char[length + 1];
strcpy(m_cStr, other.m_cStr);
return *this; //得分点:返回本对象的引用
}
std::ostream & operator<<(std::ostream & os, const String & str)
{
os << str.m_cStr;
/*
char *p = "xxxx";
std::cout << p << std::endl; // 结果:xxxx
为了省去我们循环输出字符的麻烦,cout<<p;被翻译为输出p指向的字符串值。
要输出p的指针值就只能先将其转为void *再输出。因为void型, cout没法输出,只能乖乖输出指针。
void* pV = p;
std::cout<<pV<<std::endl; // 结果:0x10e325f66(地址)
*/
return os;
}
}
// test.cpp
int main()
{
char *cStr = "hello";
test::String str(cStr);
std::cout << str << std::endl;
return 0;
}
#endif // STRING_H