string的搜索操作一共6个
1.find
size_t find (const string& str, size_t pos = 0) const;
//从调用对象的下标pos处开始查找字符串str,找到返回第一次出现str的下标,没找到,返回npos
size_t find (const char* s, size_t pos = 0) const;
//从调用对象的下标pos处开始查找字符数组s,找到返回字符数组s第一次出现的下标,否则返回npos
size_t find (const char* s, size_t pos, size_t n) const;
//从调用对象的下标pos处查找字符数组的前n个字符,找到返回前n个字符第一次出现的位置,否则返回npos
size_t find (char c, size_t pos = 0) const;
//从调用对象的位置pos处开始查找字符c,找到,返回字符c第一次出现的位置,否则返回npos
find函数是只读的,并不会改变调用对象,返回值是对应字符或字符串第一次出现的位置,是一个无符号整形数据
关于npos见博客https://blog.csdn.net/Master_Cui/article/details/107573300,npos是一个static unsigned的类型,值为-1,作为函数的参数表示字符串的结尾,作为返回值,表示没有匹配到字符串
举例
void testfind()
{
string s="1234567890";
int res=s.find("1234", 5);
if (res != string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
从字符串s的下标5的位置开始查找字符串1234,没找到,返回-1
void testfind()
{
string s="1234567890";
size_t res=s.find("1234");
if (res != string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
此时从头开始找字符串1234,找到,返回第一次出现字符串1234的下标位置0
因为成员函数find的返回值要么是一个大于0的数,要么是string::npos,所以用size_t类型的数据接受没有问题,如果想用int型数据接受,也可以,只不过当查找失败时,string::npos自动转化为-1
但是,绝对不要用0和find的返回值进行比较,因为即使查找失败,返回了string::npos,也是一个很大的数,大于0,无法判断是否查找成功
void testfind()
{
string s="1234567890";
if (s.find("1234", 3)>0) {
cout<<"find"<<endl;
}
}
正常来说是没有查找到的,但是将find的返回值和0比较,所以得出了错误的结果,所以要么用int接受find的返回值和string::npos比较,要么用size_t接受find的返回值和string::npos比较,后者更好
find的其他示例
void testfind2()
{
string s="1234567890";
size_t res=s.find('7', 4);//从下标4开始查找字符'7'
if (res != string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
void testfind3()
{
string s="1234567890";
size_t res=s.find("7891111", 4, 3);//从s的下标4位置开始,查找"7891111"的前三个字符组成的字符串
if (res != string::npos) {
cout<<"find"<<endl;
}
}
结果同上
2.rfind
size_t rfind (const string& str, size_t pos = npos) const;
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;
rfind和find相反,默认从尾到头查找,返回值是字符串或者某个字符最后一次出现在调用对象中的位置,参数形式同find
示例
void testrfind()
{
string s="1234567890";
size_t res=s.rfind("789", 2);//从下标2开始查找"789"在s中最后一次出现的位置(从"123"中查找"789"),没找到
if (res !=string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
void testrfind()
{
string s="1234567890";
size_t res=s.rfind("789");//从字符串结尾向前查找"789"最后一次出现在s中的位置
if (res !=string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
void testrfind2()
{
string s="1234567890";
size_t res=s.rfind('8', 4);//从下标4开始向前查找'8'最后一次出现在s中的位置(从"12345"中查找字符8),没找到
if (res !=string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
void testrfind2()
{
string s="1234567890";
size_t res=s.rfind("345789", 5, 2);//从下标5开始向前查找"34"第一次出现的位置
if (res !=string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
3.find_first_of
size_t find_first_of (const string& str, size_t pos = 0) const;
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;
该函数的含义是查找字符或 字符串中任意一个字符 在调用对象中第一次出现的位置。返回值是位置下标,参数含义同find和rfind
示例
void testfindfirstof()
{
string s="1234567890";
size_t res=s.find_first_of("5793");
//从s的下标位置0开始查找"3579"中任何一个字符出现在s中的位置,第一个出现的字符是'3',所以输出2
if (res!=string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
void testfindfirstof()
{
string s="1234567890";
size_t res=s.find_first_of("5793", 5);
//从s的下标位置5开始查找与"3579"中任何一个字符出现在s中的位置,第一个匹配字符是'7',所以输出下标6
if (res!=string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
void testfindfirstof()
{
string s="1234567890";
size_t res=s.find_first_of('3', 5);//从下标5开始查找字符3在s中第一次出现的位置,没有找到
if (res!=string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
void testfindfirstof()
{
string s="1234567890";
size_t res=s.find_first_of("5173", 5, 3);
//从下标5开始查找字符串"5173"中前三个字符中的任意一个字符第一次出现在s中的位置,因为字符7第一次出现,所以返回字符7在s中的下标
if (res!=string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
void testfindfirstof()
{
string s="1234567890";
size_t res=s.find_first_of("5173", 5, 2);
//从下标5开始查找"5173"中前2个字符中的任意一个字符第一次出现在s中的位置,
//因为"51"中的任何一个字符都没有出现在"67890"中,所以返回npos
if (res!=string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
4.find_first_not_of
size_t find_first_not_of (const string& str, size_t pos = 0) const;
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;
该函数和find_first_of相反,查找的是调用对象中第一个不在字符或字符串的字符的位置。很绕。。。。。。 参数形式同上
示例
void testfindfirstnotof()
{
string s="1234567890";
size_t res=s.find_first_not_of("5173");
//从s中查找第一个不在"5173"中的字符的位置,字符2是第一个不在"5173"中的字符,所以返回下标1
if (res!=string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
void testfindfirstnotof()
{
string s="1234567890";
size_t res=s.find_first_not_of("5173", 5);
//从s的下标5开始查找第一个不在"5173"中的字符的位置,字符6是第一个不在"5173"中的字符,所以返回字符6在s中的下标
if (res!=string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
void testfindfirstnotof()
{
string s="1234567890";
size_t res=s.find_first_not_of('6');//从下标0开始查找第一个不是字符6的字符
if (res!=string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
void testfindfirstnotof()
{
string s="1234567890";
size_t res=s.find_first_not_of("456", 3, 2);
//从s的下标3开始查找第一个没有出现在"456"中前两个字符中的字符,因为字符6是第一个没有出现在"45"中的字符,所以返回字符6的下标
if (res!=string::npos) {
cout<<"find"<<endl;
}
cout<<res<<endl;
}
5.find_last_of
size_t find_last_of (const string& str, size_t pos = npos) const;
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;
同find_first_of,只不过是逆向查找
6.find_last_not_of
size_t find_last_not_of (const string& str, size_t pos = npos) const;
size_t find_last_not_of (const char* s, size_t pos = npos) const;
size_t find_last_not_of (const char* s, size_t pos, size_t n) const;
size_t find_last_not_of (char c, size_t pos = npos) const;
同find_first_not_of,只不过是逆向查找
find与rfind返回的是字符或字符串整体出现的位置,而后四个函数返回的是字符或字符串中某个字符的位置
string的数值转化函数
1.各种数值转字符串
string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);
请自行品尝
2.字符串转各种数值
double stod (const string& str, size_t* idx = 0);
float stof (const string& str, size_t* idx = 0);
int stoi (const string& str, size_t* idx = 0, int base = 10);
long stol (const string& str, size_t* idx = 0, int base = 10);
long double stold (const string& str, size_t* idx = 0);
long long stoll (const string& str, size_t* idx = 0, int base = 10);
unsigned long stoul (const string& str, size_t* idx = 0, int base = 10);
unsigned long long stoull (const string& str, size_t* idx = 0, int base = 10);
示例
void testtofloat()
{
string strfloat="2.33333, a funny num";
string::size_type sz;
float f=stof(strfloat, &sz);
cout<<f<<sz<<strfloat[sz]<<endl;
}
在调用stof后,sz的值变为第一个没有参与数值转化的字符的下标,这里第一个没有参加转化的字符为逗号,所以sz的值变为,的下标
void testtointeger()
{
string binstr="101010";
string hexstr="4d56";
string octstr="123";
string autostr1="0123";
string autostr2="0xefef";
int binint=stoi(binstr, nullptr, 2);//将101010看做二进制数值转为十进制
cout<<binint<<endl;
int hexint=stoi(hexstr, nullptr, 16);//将4d56看做十六进制数转为十进制
cout<<hexint<<endl;
int octint=stoi(octstr, nullptr, 8);//将123看做八进制数转为十进制
cout<<octint<<endl;
int octnum=stoi(autostr1, nullptr, 0);//根据autostr1的格式自动转化为十进制数,因为0123是0开头,所以将0123视为八进制数
cout<<octnum<<endl;
int hexnum=stoi(autostr2, nullptr, 0);//根据autostr2的格式自动将字符串转为十进制数,因为0xefef以0x开头,所以将0xefef视为十六进制数
cout<<hexnum<<endl;
}
当把字符串转为整数时,最后一个参数表示字符串所代表数字的进制数,默认是十进制,也可以修改为其他进制
void testtointeger2()
{
string str1="0x789";
cout<<stoi(str1)<<endl;//将0x789看做十进制数,按照十进制转化,但是字符x并不是十进制数,所以只转化0,输出0
string str2="789";
string::size_type sz;
cout<<stoi(str2, &sz, 8)<<endl;//将0x789看做八进制数,按照十进制转化,但是8并不是八进制数,所以值转化7,输出7
cout<<sz<<endl;//输出第一个没有参加数值转化的字符的下标,这里第一个没有参加数值转化的字符是8,所以输出8的下标
string str4=" 77";//去掉前面的空格,输出77
cout<<stoi(str4)<<endl;
string str3=". 77";//无法转化,抛出异常
cout<<stoi(str3)<<endl;
}
通过上述输出可知,当遇到无法转化的字符串时,函数会抛出异常,当字符串前面含有空格时,函数会去掉前面的空格,再尝试转化
当开始转化时,会逐个字符读取,当字符所代表的数值与进制不匹配时,会停止读取字符串,并将已取得的字符串进行输出
参考
《C++ Primer》
《C++标准库》
http://www.cplusplus.com/reference/string/
欢迎大家评论交流,作者水平有限,如有错误,欢迎指出