目录
前言
之前说过的strlen strcpy strcat strcmp都是对于两个字符串之间来搞事情的,今天我们说的一些函数是对字符串本身来操作的。就是python中的对字符串的切片与检索。
string的查找与截取
find查找函数
这个在python中也有,具体来说是找到就返回下标,没找到就返回-1.
在C++中也是通过s来调用find的 。如果有多个需要查找的值,往往返回的是第一个被找到的下标,若想找后面的,可以在find后面加上一个参数k,表明从下标k处开始找。这个跟python中也是一样的。
int main(){
string s="hello world";
cout<<s.find('w')<<endl;//6
string s1="abc abd hello abc";
cout<<s1.find("bc")<<endl;//1
cout<<s1.find("nc",3);//15 注意这个3是闭区间从下标为3的位置开始找
}
substr截取(切片)函数
用法跟python还是有出入的,python中的切片只需交代开始截取位置与结束位置,而substr需要的是开始下标与需要截取的长度。
int main(){
string s1="abd abc hello abc";
cout<<s1.substr(4,3)<<endl;//abc
cout<<s1.substr(14)<<endl;//abc 如果只有一个参数 默认截取到尾
}
substr是有返回值的。
string的删除、插入、替换
这几个函数跟python中列表的函数有点儿相同
erase函数 删除
erase是没有返回值的,但用法基本跟substr一样。
int main(){
string s1="this is a book";
string s2="hello world";
s.erase(5,3)//在s1中删除is这个单词
s.erase(5)//删除空格后的所有单词 即world
}
insert 插入
同样也没有返回值,直接给出下标,在下标位置插入字符串。这个跟python中列表的insert基本相同。
int main(){
string s1="this is a book";
s1.erase(5,3)//s1编程 this a book
s1.insert(5,"is ")//s1变回去了
}
replace替换
python中的字符串也有replace这个函数,但是它的更为方便,直接给出旧的字符串与新的字符串即可。而且python中的replace有返回值,不会破坏原来的字符串。
word1="I am a student"
word2=word1.replace("student","teacher")
print(word2)
而C++中是要给出替换起始的下标以及替换的字符的长度,以及新的字符串。即有三个参数。
int main(){
string s1="I am a student";
s1.replace(7,7,"teacher");//会比较麻烦
cout<<s1<<endl;//I am a teacher
}
字符类型判断/转换,数组/string排序
字符类型判断函数
这个跟python中的一样的,有isdigit isalpha islower isupper
但是用法跟python不一样,python用法如下
a='1234Abc'
for i in a:
if i.isdigit():
print(i,end='')
即是python中经典使用函数的方法。
int main(){
string s;
s="1234Abc";
int len=s.size();
for (int i=0;i<len;i++){
if(isdigit(s[i])){
printf("%d",s[i]);}
}
这并不是string函数,所以并不是点引用。
但时python中返回的是bool值,C++中返回的是整数。0表示false,其他数字表示的时1.
字符类型转换函数
tolower toupper 转换为大写或小写。python中还另外提供了title 用来给每个首字母大写,另外python中大写小写分别对应的函数时upper以及lower。对应的用法与上面判断类型相似。
但是C++中的toupper返回的时ASCII码,python中返回的才是字母。
int main(){
char c='a';
cout<<toupper(c)<<endl;//65
cout<<(int) 'A'<<endl;//65
c=toupper(c);
cout<<c<<endl;//A
}
将ASCII码返回给一个字符变量时就会默认转换为对应字符。
排序(sort)和倒序(reverse)函数
sort与reverse,python中的列表有对应的操作。C++中也不是针对于字符串,而是字符数组(可改变的字符串)。
sort函数的用法
sort(起始地址,结束地址+1,func)
int main(){
int a[5]={3,2,4,1,5};
int n=5;
sort(a,a+n);
for(int i=0;i<n;i++){
cout<<a[i]<<" "<<endl;}//1 2 3 4 5
}
sort是对于数组的sort,从首地址一直到末地址,但是这个sort是一个左闭右开的玩意,所以要将结束地址+1.
sort默认是升序的,如果想要改变这种排序规则,则要调用sort后的那个func
bool cmp(int a, int b) {
if (a > b) {
return true;
} else {
return false;
}
}
int main() {
int a[5] = {3, 1, 2, 4, 5};
int n = 5;
sort(a, a + n, cmp);//直接在sort后面接上cmp函数名不要加括号
for (int i = 0; i < n; i++) {
cout << a[i]<<" ";//5 4 3 2 1
}
}
reverse用法
与sort相同。
int main(){
int a[5]={3,1,2,4,5};
reverse(a,a+5);}
注意:数组的本质是下标为0元素的地址,是一个整型指针。
获取头尾指针的函数 (begin,end)
如果我们要用sort函数对字符串进行排序呢?那么就需要获得一个字符串的头尾指针。
int main(){
string s="dskfjipfdp";
sort(s.begin(),s.end());//s.end是结束位置+1
cout<<s;//ddffijkpps
}
习题
(1)删除指定的字符
有两种方法,一种是真删除,另一种是假删除。
int main() {
string s;
char c;
cin >> s >> c;
//利用假删除
int a = s.size();
for (int i = 0; i < a; i++) {
if (s[i] != c) {
cout << s[i];
}
}
}
假删除,我不真正的去删除它,而是通过循环直接输出我需要的东西。
int main() {
string s;
char c;
cin >> s;
cin >> c;
int a = s.size(), count = 0;
for (int i = 0; i < a; ++i) {
if (s[i - count] == c) {
s.erase(i - count, 1);
count += 1;
}
}
cout << s;
}
真删除,但是这个跟python当中的列表一样,删除后下标会对应改变,所以应该加一个偏移量count。
int main() {
string s;
char c;
cin >> s >> c;
int a = s.find(c);
while (a != -1) {
s.erase(a, 1);
a = s.find(c);
}
cout << s;
}
用while循环(当循环)+find函数也可以。不去设偏移量。一直找c的下标,知道s中没有c为止
(2)查找子串并替换
用replace
int main() {
string s1, s2, s3;
getline(cin, s1);
getline(cin, s2);
getline(cin, s3);
int p1 = s1.find(s2), p2 = s2.size(), p3 = s3.size();
while (p1 != -1) {
s1.replace(p1, p2, s3);
p1 = s1.find(s2, p1 + p3);
}
cout << s1;
}
用substr+replace
int main() {
string s1, s2, s3;
getline(cin, s1);
getline(cin, s2);
getline(cin, s3);
int len1 = s1.size(), len2 = s2.size(), len3 = s3.size();
for (int i = 0; i < len1; i++) {
if (s1.substr(i, i + len2) == s2) {
s1.replace(i, len2, s3);
i += len3 - 1;
}
}
cout << s1;
}
不管是用replace还是substr都需要在使用后将下标加上对应的长度,就是让它一直向后遍历,不让它遍历修改过的字符串。