子字符串或子串或范围只是字符串字面中的一部分字符序列。知道什么是C++中的子串对程序员来说是不够的。程序员必须了解如何通过代码来识别子串。程序员必须知道如何返回一个子串。程序员必须知道如何删除一个子串。程序员必须知道如何在删除后替换一个子串。
字符串可以通过两种主要方式创建:通过const char*(array-of-char)或者从字符串类中实例化。在从字符串类实例化的情况下,必须将字符串库包含在C++程序中。在C++中识别、返回、删除和替换子串,通常只能通过从字符串类中实例化的字符串对象来完成。
字符串对象是一个具有方法(成员函数)的数据结构。它的列表由元素组成,每个元素都有一个字符。列表的值就是字符。像一个数组一样,字符串对象的每个字符都可以通过一个索引来访问。因此,一个子字符串可以通过索引来识别:一个较低索引和一个较高索引。范围从低索引开始到高索引,不包括高索引。高索引的字符不包括在这个范围内,子串的长度是从低索引的字符到高索引的字符之前的字符。
两个迭代器也可以识别一个子串或范围:第一个迭代器是范围的开始,而最后一个迭代器,是在实际的最后一个字符之后的字符(或在字符串的末端)。迭代器和索引之间有一个简单的关系--见下文。
这篇文章解释了什么是子串以及如何在C++中识别、返回、删除和替换子串。
文章内容
识别和返回一个子串
C++类有一个成员函数,叫做substr(),用于子串()。其语法是:
basic_string substr(size_type pos = 0, size_type n = npos) const
这个函数将子串作为一个字符串对象返回。第一个参数表示子串开始的索引位置。pos的字符被包含在子串中。第二个参数给出了子串的长度。长度是指从pos开始的字符数。它不包括较高索引的字符。更高的索引是:pos + npos (虽然长度,npos是向左移了一个位置)。索引计数从零开始。 下面的程序说明了这个成员函数的使用。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str = "one_two_three_four_five";
string substrin = str.substr(8, 5);
cout <<substrin <<endl;
return 0;
}
输出结果是
three
如果没有这两个参数,就会考虑整个字符串,正如下面的程序所说明的。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str = "one_two_three_four_five";
string substrin = str.substr();
cout <<substrin <<endl;
return 0;
}
输出结果是
one_two_three_four_five
语法末尾的保留词,const,意味着substr()函数复制了子串并返回它。它不会删除该子串。
迭代器和索引的关系
当一个迭代器指向一个字符时,为了得到区间末端的迭代器,只需加上区间的字符长度(数量),新的迭代器就会指向区间的末端。这最后一个迭代器的字符不包括在范围或子串中。这里的range和substring是同一件事(它们在上面是同一件事)。对于substr()字符串成员函数,npos是区间的长度。
与索引0相对应的迭代器是。
str.begin()
npos可以被添加到这个迭代器中,以指向区间的最后一个元素。区间的最后一个元素或最后一个字符不是子串的一部分。
对应于字符串最后一个字符后的那一点的迭代器是。
str.end()
npos可以从中减去,以便指向任何想要的字符串的第一个字符。
begin()和end()是字符串类的成员函数。
删除一个子串
一个子串在一个字符串对象中被识别,其参数是substr()函数的pos和npos。回顾一下,npos是一个区间。字符串类也有一个叫做eras()的成员函数。eras()有重载形式。其中一个重载的erase()成员函数用pos和npos来识别子串。语法是。
basic_string& erase(size_type pos = 0, size_type n = npos)
这个擦除函数删除了子串,并返回删除子串后的原始字符串。
所以,要删除一个子串,不需要使用substr()函数。需要的是它的参数。要删除一个子串,请使用字符串对象的erase成员函数。要想拥有一个子串的副本,只需在擦除前使用substr()函数。下面的程序展示了一个删除子串的好方法。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str = "one_two_three_four_five";
string substrin = str.substr(8, 5);
string ret = str.erase(8, 5);
cout <<substrin <<endl;
cout <<str <<endl;
cout <<ret <<endl;
return 0;
}
输出结果是
three
one_two__four_five
one_two__four_five
一个用迭代器参数删除子串的语法是。
iterator erase(const_iterator first, const_iterator last)
这样,子串的开头首先由迭代器确定,对应于索引,pos。为了获得子串的结尾,迭代器由last来识别,last是由first + npos获得的。使用这个重载的erase()函数来删除一个子串的代码,将作为一个练习留给读者。
替换一个子串
真正识别一个子串的是参数:pos和npos.要返回一个子串,请使用字符串类成员函数substr()。要删除一个子串,请使用字符串类的成员函数,eras()。要用一个任意长度的子串来替换一个子串,请使用字符串类成员函数,replace()。replace函数有许多重载的变体。其中使用索引的是
basic_string& replace(size_type pos1, size_type n1, const T& t)
其中pos1是pos,n1是npos,而t是一个独立的字符数组,用于替换。它返回原始字符串,包括替换后的字符串。
注意:在C++中,一个子串在被替换之前不应该被删除(擦除)。
下面的程序展示了一个替换子串的好方法。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str = "one_two_three_four_five";
char chs[] = "ccc";
string substrin = str.substr(8, 5);
string ret = str.replace(8, 5, chs);
cout <<substrin <<endl;
cout <<str <<endl;
cout <<ret <<endl;
return 0;
}
输出结果是
three
one_two_ccc_four_five
one_two_ccc_four_five
上述代码的替换长度小于5个字符。下面的程序显示了替换量大于5个字符的情况。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str = "one_two_three_four_five";
char chs[] = "cccccccc";
string substrin = str.substr(8, 5);
string ret = str.replace(8, 5, chs);
cout <<substrin <<endl;
cout <<str <<endl;
cout <<ret <<endl;
return 0;
}
three
one_two_cccccccc_four_five
one_two_cccccccc_four_five
用迭代器参数替换子串的语法是
basic_string& replace(const_iterator i1, const_iterator i2, const T& t)
在这个语法中,子串的开头是由迭代器i1确定的,它对应的索引是pos。为了获得子串的结尾,迭代器由i2来识别,i2是通过i1 + npos获得的。下面的程序显示了如何使用这种语法。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str = "one_two_three_four_five";
string::const_iterator itB = str.begin();
string::const_iterator itPos = itB + 8;
string::const_iterator itNpos = itPos + 5;
char chs[] = "ccccc";
string substrin = str.substr(8, 5);
string ret = str.replace(itPos, itNpos, chs);
cout <<substrin <<endl;
cout <<str <<endl;
cout <<ret <<endl;
return 0;
}
输出结果是
three
one_two_ccccc_four_five
one_two_ccccc_four_five
注意,使用的迭代器是常数迭代器。与索引pos相对应的迭代器是用itB+8得到的。对应于较高索引的迭代器是用itPos + 5得到的。
结论
一个子串或子串或范围只是一个字符串字面中的一部分字符序列。要返回一个子串,可以使用字符串类的成员函数substr()。要删除一个子串,请使用字符串类的成员函数,eras()。要替换一个子串,请使用字符串类成员函数,replace()。对于所有这些函数,索引参数pos和索引区间npos是识别主字符串子串的关键。