C++ 字符串类(string class)使用详解

文档声明:
以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正。并且该文档在后期会随着学习的深入不断补充完善。

资料仅供学习交流使用。
作者:Aliven888

String class:字符串是代表字符序列的对象。

标准字符串类通过类似于标准字节容器的接口为此类对象提供支持,但增加了专门设计用于单字节字符字符串的功能。

字符串类是basic_string类模板的实例化,该模板使用char(即字节)作为其字符类型,并具有其默认的char_traits和分配器类型(有关模板的更多信息,请参见basic_string)。

请注意,此类处理字节独立于所使用的编码:如果用于处理多字节或可变长度字符(例如UTF-8)的序列,则此类的所有成员(例如长度或大小)以及 它的迭代器仍将以字节为单位(而不是实际的编码字符)进行操作。

2、接口函数

2.1、成员函数(Member functions):

find_last_not_of Find non-matching character in string from the end (public member function) substr Generate substring (public member function) compare Compare strings (public member function)

2.7、成员变量:

方式4 : char *chA = "1234567890"; std::string strD(chA); //定义一个strD字符串类型,并使用chA赋值。 strD = "1234567890"; 方式5 : const char *chB = "test-string"; std::string strE(chB, 4);//定义一个strE字符串类型,并使用strB位置区间在[0 - 4]的子串赋值。 strE = "test"; 方式6 : std::string strF(6, 'A'); //定义一个strF字符串类型,并使用 6个‘A’赋值。 strF = "AAAAAA"; 方式7 : std::string strG(strF.begin(), strF.begin()+2); //定义一个strG字符串类型,并使用 strF 位置区间在[0 - 2]的子串 赋值。 strF = "AA";

3.1.2、析构函数(destructor)

使用实例:

//无需关心,std::string 的 对象释放时自动调用。
~string(); 

3.1.3、运算符重载(operator=)

<font color = "#e3a869">使用实例:</font>

std::string strA = "assss";   //使用默认字符串赋值。
std::string strB = strA;  //使用已存在的对象赋值。

3.2、迭代器(Iterators):

std::string 可以理解为一个容器,里面存储的都有字符,通过迭代器我们可以实现对字符串中的字符进行操作。

下面介绍下 std::string 支持的迭代器,以及使用。

std::string str = "1234567890";
std::string::const_iterator itBegin = str.begin();
cout << "str.begin() = " << *itBegin << endl;    //输出:str.begin() = '1'
std::string::const_iterator itEnd = str.end();
cout << "str.end() = " << *itEnd << endl;  //输出:str.end() = '\0'
std::string::reverse_iterator itrBegin = str.rbegin();
cout << "str.rbegin() = " <<  *itrBegin << endl;  //输出:str.rbegin() = '0'
std::string::reverse_iterator itrEnd = str.rend();
cout << "str.rend() = " << *itrEnd << endl;  //输出:str.end() = '\0'
std::string::const_iterator itcBegin = str.cbegin();
cout << "str.cbegin() = " << *itcBegin << endl;    //输出:str.begin() = '1'
std::string::const_iterator itcEnd = str.cend();
cout << "str.cend() = " << *itcEnd << endl;  //输出:str.end() = '\0'
std::string::const_reverse_iterator itcrBegin = str.crbegin();
cout << "str.crbegin() = " << *itcrBegin << endl;  //输出:str.rbegin() = '0'
std::string::const_reverse_iterator itcrEnd = str.crend();
cout << "str.crend() = " << *itcrEnd << endl;  //输出:str.end() = '\0'

输出打印:
注意:因为 '\0' 输出打印不显示,所以下面显示为空。
std::string str = "1234567890"; int strSize = str.size(); //strSize = 10; int strLen = str.size(); //strLen = 10;

3.3.2、获取最大长度(max_size)

使用实例:

//返回字符串可以达到的最大长度。
//由于已知的系统或库实现限制,这是字符串可以达到的最大潜在长度,但是不能保证对象能够达到该长度:
//在达到该长度之前,它仍然可能无法在任何时候分配存储。
std::string str = "1234567890";
int strMax_Size = str.max_size();   //strMax_Size = 10;

3.3.3、删除操作(resize)

使用实例:

//删除字符串中的字符。
//删除字符串的一部分,以减小其长度。
std::string str = "1234567890";
//删除字符串值中从字符位置pos开始并跨越len个字符的部分(如果内容太短或len是string :: npos则一直到字符串的末尾)。
//请注意,默认参数会擦除字符串中的所有字符(例如成员函数clear)。
//string& erase (size_t pos = 0, size_t len = npos);
str.erase(0, 2);     //此时 str = “34567890”;
//删除p指向的字符。
//iterator erase (const_iterator p);
std::string::iterator it = str.begin();
str.erase(it);     //此时 str = “4567890”;
//擦除[first,last)范围内的字符序列。
std::string::iterator it = str.begin();
str.erase(it, it+3);     //此时 str = “7890”;

3.3.4、获取容量(capacity)

使用实例:

//返回当前为字符串分配的存储空间的大小,以字节表示。
//此容量不一定等于字符串长度。它可以相等或更大,当将新字符添加到字符串时,多余的空间可使对象优化其操作。
std::string str = "1234567890";
int cLen = str.capacity();
cout << "str.capacity() = " << cLen << endl;

输出实例:
注意:实际长度是 10,但是 capacity() 获取的是:15

//请求根据计划的大小更改将字符串容量调整为最多n个字符的长度。
//如果n大于当前字符串容量,则该函数使容器将其容量增加到n个字符(或更大)。
//经过测试发现,重置后的容量不一定是n,也有可能是比n大的数。
std::string str = "1234567890";
cout << "str.capacity() = " << str.capacity() << endl;
str.reserve(0x10);
cout << "str.capacity() = " << str.capacity() << endl;

输出打印:
注意:经过测试发现,重置后的容量不一定是n,也有可能是比n大的数。
cout << "str.length() = " << str.length() << endl; str.clear(); cout << "str.length() = " << str.length() << endl;

输出打印:
std::string str = "1234567890"; str.reserve(0x20); cout << "str.capacity() = " << str.capacity() << endl; str.shrink_to_fit(); cout << "str.capacity() = " << str.capacity() << endl;

输出打印:

//接口:operator+=
//  string& operator+= (const string& str);
//  string& operator+= (const char* s);
//  string& operator+= (char c);
//功能:字符串与字符串(字符)相加
//eg:
std::string strA = "12345";
std::string strB = "67890";
const char *chpBuf = "AAAA";
char chBuf = 'B';
strA += strB;
cout << "strA += strB  --> " << strA << endl;
strA += chpBuf;
cout << "strA += chpBuf  --> " << strA << endl;
strA += chBuf;
cout << "strA += chBuf   --> " << strA << endl;

输出打印:

//接口:
//  string& append (const string& str);
//  string& append (const string& str, size_t subpos, size_t sublen);
//  string& append (const char* s);
//  string& append (const char* s, size_t n);
//  string& append (size_t n, char c);
//  template <class InputIterator>
//    string& append (InputIterator first, InputIterator last);
//功能:在字符串后面添加一个字符或者字符串
//eg:
std::string strA = "12345";
std::string strB = "67890";
std::string strC = "ABCDE";
std::string strD = "FGHIJ";
const char *chpBuf = "KLMNO";
strA.append(strB);
cout << "strA.append(strB) = " << strA << endl;
strA.append(strC, 1, 3);
cout << "strA.append(strC, 1, 3) = " << strA << endl;
strA.append(chpBuf);
cout << "strA.append(chpBuf) = " << strA << endl;
strA.append(chpBuf, 3);
cout << "strA.append(chpBuf, 3) = " << strA << endl;
strA.append(3, 'H');
cout << "strA.append(3, 'H') = " << strA << endl;
strA.append(strD.begin(), strD.begin()+2);
cout << "strA.append(strD.begin(), strD.begin()+2) = " << strA << endl;

输出打印:

//接口:
//  string& assign(const string& str);
//  string& assign(const string& str, size_t subpos, size_t sublen);
//  string& assign(const char* s);
//  string& assign(const char* s, size_t n);
//  string& assign(size_t n, char c);
//  template <class InputIterator>
//      string& assign(InputIterator first, InputIterator last);
//功能:为字符串分配一个新值,替换其当前内容。
//eg:
std::string strA = "12345";
std::string strB = "67890";
std::string strC = "ABCDE";
std::string strD = "FGHIJ";
const char *chpBuf = "KLMNO";
strA.assign(strB);
cout << "strA.assign(strB) = " << strA << endl;
strA.assign(strC, 1, 3);
cout << "strA.assign(strC, 1, 3) = " << strA << endl;
strA.assign(chpBuf);
cout << "strA.assign(chpBuf) = " << strA << endl;
strA.assign(chpBuf, 3);
cout << "strA.assign(chpBuf, 3) = " << strA << endl;
strA.assign(3, 'H');
cout << "strA.assign(3, 'H') = " << strA << endl;
strA.assign(strD.begin(), strD.begin()+2);
cout << "strA.assign(strD.begin(), strD.begin()+2) = " << strA << endl;

输出打印:

//接口:
//  string& insert(size_t pos, const string& str);
//  string& insert(size_t pos, const string& str, size_t subpos, size_t sublen);
//  string& insert(size_t pos, const char* s);
//  string& insert(size_t pos, const char* s, size_t n);
//  string& insert(size_t pos, size_t n, char c);
//     void insert(iterator p, size_t n, char c);
//  iterator insert(iterator p, char c);
//  template <class InputIterator>
//     void insert(iterator p, InputIterator first, InputIterator last);
//功能:在字符串中,pos(或p)指向的字符之前,插入其他字符
//eg:
std::string strA = "12345";
std::string strB = "67890";
std::string strC = "ABCDE";
std::string strD = "FGHIJ";
const char *chpBuf = "KLMNO";
strA.insert(2, strB);
cout << "strA.insert(2, strB) = " << strA << endl;
strA.insert(2, strC, 1, 3);
cout << "strA.insert(2, strC, 1, 3) = " << strA << endl;
strA.insert(2, chpBuf);
cout << "strA.insert(2, chpBuf) = " << strA << endl;
strA.insert(2, chpBuf, 3);
cout << "strA.insert(2, chpBuf, 3) = " << strA << endl;
strA.insert(2, 3, 'H');
cout << "strA.insert(2, 3, 'H') = " << strA << endl;
strA.insert(strA.begin(), 3, 'W');
cout << "strA.insert(strA.begin(), 3, 'W') = " << strA << endl;
strA.insert(strA.begin(), 'Q');
cout << "strA.insert(strA.begin(), 'Q') = " << strA << endl;
strA.insert(strA.begin(), strD.begin(), strD.end());
cout << "strA.insert(strA.begin(), strD.begin(), strD.end()) = " << strA << endl;
//  string& erase(size_t pos = 0, size_t len = npos);
//  iterator erase(iterator p);
//  iterator erase(iterator first, iterator last);
//功能:清除字符串的一部分,以减小其长度。
//eg:
std::string strA = "1234567890";
strA.erase(0, 2);
cout << "strA.erase(0, 2) = " << strA << endl;
strA = "1234567890";  //还原字符串值
strA.erase(strA.begin()+2);
cout << "strA.erase(strA.begin()+2) = " << strA << endl;
strA = "1234567890";  //还原字符串值
strA.erase(strA.begin() + 2, strA.begin() + 5);
cout << "strA.(strA.begin() + 2, strA.begin() + 5) = " << strA << endl;

输出打印:

//接口:
// string& replace(size_t pos, size_t len, const string& str);
// string& replace(iterator i1, iterator i2, const string& str);
// string& replace(size_t pos, size_t len, const string& str,size_t subpos, size_t sublen);
// string& replace(size_t pos, size_t len, const char* s);
// string& replace(iterator i1, iterator i2, const char* s);
// string& replace(size_t pos, size_t len, const char* s, size_t n);
// string& replace(iterator i1, iterator i2, const char* s, size_t n);
// string& replace(size_t pos, size_t len, size_t n, char c);
// string& replace(iterator i1, iterator i2, size_t n, char c);
// template <class InputIterator>
//   string& replace(iterator i1, iterator i2, InputIterator first, InputIterator last);
//功能:用新内容替换以字符pos开头并跨越len个字符(或[i1,i2之间的范围内的字符串部分])的字符串部分:
//eg:
std::string strA = "1234567890";
std::string strB = "ABCDEFGHIJ";
const char *chpBuf = "@#$%&*()[?";
strA = "1234567890";
strA.replace(1, 2, strB);
cout << "strA.replace(1, 2, strB) = " << strA << endl;
strA = "1234567890";
strA.replace(strA.begin(), strA.begin() + 2, strB);
cout << "strA.replace(strA.begin(), strA.begin() + 2, strB) = " << strA << endl;
strA = "1234567890";
strA.replace(1, 2, strB, 3, 7);
cout << "strA.replace(1, 2, strB, 3, 7) = " << strA << endl;
strA = "1234567890";
strA.replace(1, 2, chpBuf);
cout << "strA.replace(1, 2, chpBuf) = " << strA << endl;
strA = "1234567890";
strA.replace(strA.begin()+2, strA.begin()+3, chpBuf);
cout << "strA.replace(strA.begin()+2, strA.begin()+3, chpBuf) = " << strA << endl;
strA = "1234567890";
strA.replace( 5, 3, chpBuf, 5);
cout << "strA.replace(strA.begin()+2, strA.begin()+3, chpBuf) = " << strA << endl;
strA = "1234567890";
strA.replace(strA.begin(), strA.begin() + 2, chpBuf, 5);
cout << "strA.replace(strA.begin(), strA.begin() + 2, chpBuf, 5) = " << strA << endl;
strA = "1234567890";
strA.replace(5, 3, 5, 'G');
cout << "strA.replace(5, 3, 5, 'G') = " << strA << endl;
strA = "1234567890";
strA.replace(strA.begin() + 2, strA.begin() + 3, 6, 'S');
cout << "strA.replace(strA.begin() + 2, strA.begin() + 3, 6, 'S') = " << strA << endl;
strA = "1234567890";
strA.replace(strA.begin() + 2, strA.begin() + 3,  strB.begin(), strB.end());
cout << "strA.replace(strA.begin() + 2, strA.begin() + 3,  strB.begin(), strB.end()) = " << strA << endl;

输出打印:
std::string strA = "1234567890"; const char *chA = strA.c_str(); cout << "strA.c_str() = " << chA << endl;

输出打印:

//接口:
//  size_t find(const string& str, size_t pos = 0) const noexcept;
//  size_t find(const char* s, size_t pos = 0) const;
//  size_t find(const char* s, size_t pos, size_type n) const;
//  size_t find(char c, size_t pos = 0) const noexcept;
//str
//要搜索的字符串。
//pos
//搜索中要考虑的字符串中第一个字符的位置(搜索的起点)。
//如果该长度大于字符串长度,则该函数将永远找不到匹配项。
//注意:第一个字符由0值表示(不是1):0值表示搜索整个字符串。
//指向字符数组的指针。
//如果指定了参数n(3),则要匹配的序列是数组中的前n个字符。
//否则(2),期望以空字符结尾的序列:要匹配的序列的长度由首次出现的空字符确定。
//要匹配的字符序列的长度。
//要搜索的单个字符。
//功能:在字符串内查找目标字符子串或者字符,并返回查到的第一个位置。
//如果指定了pos,则搜索仅在位置pos或之后的字符,
//而忽略包括pos之前的任何可能出现的字符。
//eg:
std::string strA = "1234567890";
std::string strB = "34";
const char *chpBuf = "78";
cout << "strA.find(strB) = " << strA.find(strB) << endl;
cout << "strA.find(chpBuf) = " << strA.find(chpBuf) << endl;

|rfind|Find last occurrence of content in string (public member function)|

3.6.5、查找最后一次出现位置(rfind)

使用方式:

//接口:
size_t rfind(const string& str, size_t pos = npos) const noexcept;
size_t rfind(const char* s, size_t pos = npos) const;
size_t rfind(const char* s, size_t pos, size_t n) const;
size_t rfind(char c, size_t pos = npos) const noexcept;
待搜索的字符子串。
字符串中最后一个字符的位置将被视为匹配的开始。
任何大于或等于字符串长度的值(包括string :: npos)意味着将搜索整个字符串。
注意:第一个字符由0值表示(不是1)。
指向字符数组的指针。
如果指定了参数n(3),则要匹配的序列是数组中的前n个字符。
否则(2),期望以空字符结尾的序列:要匹配的序列的长度由首次出现的空字符确定。
待匹配的字符序列的长度。
待搜索的单个字符。
//功能:
//查找字符串中最后出现的位置。
//如果指定了pos,则搜索仅包括在位置pos或之前开始的字符序列,
//而忽略从pos之后开始的任何可能的匹配。

3.6.6、查找第一次出现位置(find_first_of)

使用方式:

//接口:
size_t find_first_of (const string& str, size_t pos = 0) const noexcept;    
size_t find_first_of (const char* s, size_t pos = 0) const;
size_t find_first_of (const char* s, size_t pos, size_t n) const;
size_t find_first_of (char c, size_t pos = 0) const noexcept;
待搜索的字符子串。
字符串中最后一个字符的位置将被视为匹配的开始。
任何大于或等于字符串长度的值(包括string :: npos)意味着将搜索整个字符串。
注意:第一个字符由0值表示(不是1)。
指向字符数组的指针。
如果指定了参数n(3),则要匹配的序列是数组中的前n个字符。
否则(2),期望以空字符结尾的序列:要匹配的序列的长度由首次出现的空字符确定。
待匹配的字符序列的长度。
待搜索的单个字符。
在字符串中搜索指定字符后者字符子串的第一个位置。
如果指定了pos,则搜索仅包括位置pos或之后的字符,而忽略pos之前可能出现的任何字符。

3.6.7、查找最后一次出现位置(find_last_of)

使用方式:

//接口:
size_t find_last_of (const string& str, size_t pos = npos) const noexcept;
size_t find_last_of (const char* s, size_t pos = npos) const;
size_t find_last_of (const char* s, size_t pos, size_t n) const;
size_t find_last_of (char c, size_t pos = npos) const noexcept;
待搜索的字符子串。
字符串中最后一个字符的位置将被视为匹配的开始。
任何大于或等于字符串长度的值(包括string :: npos)意味着将搜索整个字符串。
注意:第一个字符由0值表示(不是1)。
指向字符数组的指针。
如果指定了参数n(3),则要匹配的序列是数组中的前n个字符。
否则(2),期望以空字符结尾的序列:要匹配的序列的长度由首次出现的空字符确定。
待匹配的字符序列的长度。
待搜索的单个字符。
在字符串中搜索指定字符或者字符子串出现最后一次的位置。
如果指定了pos,则搜索仅包括位置pos或之前的字符,而忽略pos之后的任何可能出现的情况。

3.6.8、查找第一个不匹配(find_first_not_of)

使用方式:

//接口:
size_t find_first_not_of (const string& str, size_t pos = 0) const noexcept;
size_t find_first_not_of (const char* s, size_t pos = 0) const;
size_t find_first_not_of (const char* s, size_t pos, size_t n) const;
size_t find_first_not_of (char c, size_t pos = 0) const noexcept;
另一个字符串,其中包含要在目标字符串中搜索使用的字符集。
搜索中要考虑的字符串中第一个字符的位置。
如果该长度大于字符串长度,则该函数将永远找不到匹配项。
注意:第一个字符由0值表示(不是1):0值表示搜索整个字符串。
指向字符数组的指针。
如果指定了参数n(3),则在搜索中使用数组中的前n个字符。
否则(2),期望以空字符结尾的序列:具有在搜索中使用的字符的序列的长度由首次出现的空字符确定。
要搜索的字符值的数量。
要搜索的单个字符。
在字符串中搜索与字符集中指定的任何一个字符都不匹配的第一个字符的位置。
如果指定了pos,则搜索仅包括位置pos或之后的字符,而忽略该字符之前的任何可能出现的情况。
std::string strA = "1234567890";
cout << "strA.find_first_not_of(\"32154r56\") = " << strA.find_first_not_of("32154r56") << endl;

输出打印:
字符 ‘7’ 不在字符串 “"32154r56” 中, 而字符 ‘7’ 的位置是 ipos = 6.

//接口:
size_t find_last_of (const string& str, size_t pos = npos) const noexcept;
size_t find_last_of (const char* s, size_t pos = npos) const;
size_t find_last_of (const char* s, size_t pos, size_t n) const;
size_t find_last_of (char c, size_t pos = npos) const noexcept;
另一个包含要搜索字符的字符串。
搜索中要考虑的字符串中最后一个字符的位置。
任何大于或等于字符串长度的值(包括string :: npos)都表示要搜索整个字符串。
注意:第一个字符由0值表示(不是1)。
指向字符数组的指针。
如果指定了参数n(3),则搜索数组中的前n个字符。
否则(2),期望以空字符结尾的序列:具有匹配字符的序列的长度由首次出现的空字符确定。
要搜索的字符值的数量。
要搜索的单个字符。
在字符串中搜索与参数中指定的任何字符匹配的最后一个字符。
如果指定了pos,则搜索仅包括位置pos或之前的字符,而忽略pos之后的任何可能出现的情况。
匹配的最后一个字符的位置。
如果未找到匹配项,则该函数返回string :: npos。
//eg:
std::string strA = "123456789055F";
cout << "strA.find_last_not_of(\"54rsd\") = " << strA.find_last_not_of("54rsd3") << endl;

输出打印:
字符 ‘F’ 不在字符串 "54rsd3” 中, 而字符 ‘F’ 的位置是 ipos = 12.
//eg: std::string strA = "123456789055F"; cout << "strA.substr(2, 5) = " << strA.substr(2, 5) << endl;

输出打印:
int compare (const string& str) const noexcept; int compare (size_t pos, size_t len, const string& str)const; int compare (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen) const; int compare (const char* s) const; int compare (size_t pos, size_t len, const char* s) const; int compare (size_t pos, size_t len, const char* s, size_t n) const; 另一个字符串对象,完全(或部分)用作比较字符串。 比较字符串中第一个字符的位置。 如果该长度大于字符串长度,则抛出out_of_range。 注意:第一个字符由0值表示(不是1)。 比较的字符串的长度(如果字符串较短,则尽可能多的字符)。 string :: npos的值表示直到字符串末尾的所有字符。 subpos,sublen 与上面的pos和len相同,但用于比较字符串。 指向字符数组的指针。 如果指定了参数n(4),则将数组中的前n个字符用作比较字符串。 否则(3),将期望以空字符结尾的序列:具有用作比较字符串的字符的序列的长度由空字符的第一次出现来确定。 要比较的字符数。 功能:将字符串对象(或子字符串)的值与其参数指定的字符序列进行比较。