一般我们在C语言中用到字符串,都是使用字符数组来存放,但是操作字符数组有时候会不便,所以为了方便操作,在C++的STL中加入了字符串类型(string)。
想要复习以往字符数组的相关知识点请点击以下链接:
字符串的输入输出
字符串操作
字符串的sscanf和sprintf(选看)
如果要使用 string,需要添加 string头文件,即# include<string> (注意 string. h 和 string 是不一样的头文件)。除此之外,还需要在头文件下面加上一句:“ using namespace std"。
string类型的输入:使用getline;请参考:cin/cout与getline
1.string的定义和初始化:
定义和初始化和普通的数据类型一样:
string str;
str = "abcd";
//或者可以在定义的同时初始化
string str = "abcd";
2.string中内容的访问:
(1)通过下标访问
-
一般来说,可以直接像访问字符数组那样去访问string:
程序代码:
#include<cstdio>
#include<string>
using namespace std;
int main(){string str = "abced";for(int i=0;i<str.length();i++){printf("%c ",str[i]);}return 0;
}
运行结果:
-
如果要读入和输出整个字符串,则只能使用cin和cout:
程序代码:
//cin和cout在iostream头文件中,而不是stdio.h
#include<iostream>
#include<string>
using namespace std;
int main(){string str;cin>>str;cout<<str<<endl;return 0;
}
运行结果:
对输入的任意字符串,原样输出。
-
scanf和printf来输入输出string的方法——用c_str()将string类型转换为字符数组类型输出。示例如下
程序代码:
#include<cstdio>
#include<string>
using namespace std;
int main(){string str;scanf("%s",str.c_str()); //将str转换为字符数组类型输入 printf("%s\n",str.c_str()); //将str转换为字符数组类型输出 return 0;
}
运行结果:
(2)通过迭代器访问
一般仅通过(1)就可以满足访问的要求,但是有些函数比如insert()和erase()则要求以迭代器为参数,所以还是学一下迭代器的用法。
- 定义迭代器:
string::iterator it;
这样就可以得到迭代器it,并且可以通过*it来访问string里的每一位:
程序代码:
#include<cstdio>
#include<string>
using namespace std;
int main(){string str = "abcd"; for(string::iterator it = str.begin();it !=str.end();it++) {printf("%c",*it); }return 0;
}
运行结果:
string和vector语言,支持直接对迭代器进行加减某个数字,如str.begin()+3的写法是可行的。
3.string常用函数示例解析:
(1)operator+=
string的加法,可以将两个string直接拼接起来。
程序代码:
#include<iostream>
#include<string>
using namespace std;
int main(){string str1 = "lichuachua",str2 = "aixuexi",str3; str3 = str1+str2;str1+=str2;cout<<str1<<endl;cout<<str3<<endl;return 0;
}
运行结果:
(2)compare operator
两个string类型可以直接使用==、!=、<=、<、>、>=比较大小,比较规则是字典序。
程序代码:
#include<iostream>
#include<string>
using namespace std;
int main(){string str1 = "aa",str2 = "aaa",str3 = "abc",str4 = "xyz"; if(str1<str2) printf("ok1\n");if(str1!=str3) printf("ok2\n");if(str4>=str3) printf("ok3\n");return 0;
}
运行结果:
(3)length()/size()
length()返回string的长度,即存放的字符数,时间复杂度为O(1)。size()基本相同。
程序代码:
#include<iostream>
#include<string>
using namespace std;
int main(){string str = "lichuachua"; printf("%d %d\n",str.length(), str.size()); return 0;
}
运行结果:
(4)insert()
insert()常用写法,时间复杂度O(N)。
- insert(pos,string),在pos号位置插入字符串string。
程序代码:
#include<iostream>
#include<string>
using namespace std;
int main(){string str = "lichuachua"; str.insert(2, "***");cout<<str<<endl;return 0;
}
运行结果:
- insert(it,it2,it3),it为原字符串的欲插入位置,it2和it3为待插字符串的首尾迭代器,用来表示串[it2,it3)将被插在it的位置上。
程序代码:
#include<iostream>
#include<string>
using namespace std;
int main(){string str = "lichuachua",str1 = "***"; //在str的2号位(即i和第一个c之间)插入 str1 str.insert(str.begin()+2,str1.begin(),str1.end());cout<<str<<endl;return 0;
}
运行结果:
(5)erase()
erase()两种用法:删除单个元素和删除一个区间内的所有元素。时间复杂度O(N)。
- 删除单个元素。
str.erase(it)用于删除单个元素,it为所需要的单个元素的迭代器。
程序代码:
#include<iostream>
#include<string>
using namespace std;
int main(){string str = "lichuachua"; str.erase(str.begin()+1);//删除1号位(从0开始),即 i cout<<str<<endl;return 0;
}
运行结果:
- 删除一个区间内的所有元素。
①str.erase(first, last),其中first为需要删除的区间的起始迭代器,而last则为需要删除区间的末尾送代器的下一个地址,也即为删除[first,last)。
程序代码:
#include<iostream>
#include<string>
using namespace std;
int main(){string str = "lichuachua"; //删除[str.begin()+1,str.end()-3] 内的元素,即ichuac str.erase(str.begin()+1,str.end()-3); cout<<str<<endl;return 0;
}
运行结果:
②str.erase(pos, length),其中pos为需要开始删除的起始位置, length为删除的字符个数。
程序代码:
#include<iostream>
#include<string>
using namespace std;
int main(){string str = "lichuachua"; str.erase(1,6); //从1号位的i开始删除6个cout<<str<<endl;return 0;
}
运行结果:
(6)clear()
clear()用以清空string中的数据,时间复杂度一般我O(1)。
程序代码:
#include<iostream>
#include<string>
using namespace std;
int main(){string str = "lichuachua"; cout<<"原字符个数 = "<<str.size()<<endl;str.clear(); //清空字符串 cout<<"现字符个数 = "<<str.length()<<endl;return 0;
}
运行结果:
(7)substr()
substr(pos,len)返回从pos号位开始、长度为len的子串,时间复杂度为O(len)。
程序代码:
#include<iostream>
#include<string>
using namespace std;
int main(){string str = "lichuachua ai xuexi"; cout<<str.substr(0,10)<<endl;cout<<str.substr(11,2)<<endl;cout<<str.substr(14,5)<<endl;return 0;
}
运行结果:
(8)string::npos
string:npos是一个常数,其本身的值为-1,但由于是 unsigned_int类型,因此实际上也可以认为是unsigned_int类型的最大值。string:npos用以作为find函数失配时的返回值。例如在下面的实例中可以认为 string::npos等于-1,有的资料里面会写 string::npos等于4294967295,我的PC上不是。
程序代码:
#include<iostream>
#include<string>
using namespace std;
int main(){cout<<"UINT_MAX:"<<UINT_MAX<<endl; //打印unsigned_int类型的最大值if(string::npos == -1) {cout<<"-1 is true "<<endl;}if(string::npos == UINT_MAX) {cout<<"4294967295 is true "<<endl;}if(string::npos == 4294967295) {cout<<"4294967295 is true "<<endl;}return 0;
}
运行结果:
注意:这里每个人有可能不同
(9) find()
str.find(str2),当str2是str的子串时,返回其在str中第一次出现的位置;如果str2不是str的子串,那么返回 string::npos。
str_find(str2,pos),从str的pos号位开始匹配str2,返回值与上相同。
时间复杂度为O(nm),其中n和m分别为str和str2的长度。
程序代码:
#include<iostream>
#include<string>
using namespace std;
int main(){string str = "Thank you for your smile"; string str1 = "you"; string str2 = "me";if(str.find(str1) != string::npos) {cout<<str.find(str1)<<endl;}if(str.find(str1,7) != string::npos) {cout<<str.find(str1,7)<<endl;}if(str.find(str2) != string::npos) {cout<<str.find(str2)<<endl;}else {cout<<"不存在"<<endl;}return 0;
}
运行结果:
(10)replace()
str.replace(pos,len,st2)把str从pos号位开始、长度为len的子串替换为str2。
str.replace(it1,it2,str2)把str的迭代器[it1,it2)范围的子串替换为str2。
时间复杂度为O( str.length)。
程序代码:
#include<iostream>
#include<string>
using namespace std;
int main(){string str = "maybe you will turn around"; string str2 = "will not"; string str3 = "surely"; cout<<str.replace(10,4,str2)<<endl;cout<<str.replace(str.begin(),str.begin()+5,str3)<<endl;return 0;
}
运行结果: