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
posted on 2020-04-14 16:26  JJ_S  阅读(268)  评论(0编辑  收藏  举报