一、概念
1.1相关概念
0C++中有两种字符串表示形式:C风格字符串和string类类型。
C风格字符串是
- 字符数组使用null字符\0终止的一维字符数组,
- 字符指针是一个指针变量,里面存放一个字符的地址
而string类处理起字符串来会方便很多,完全可以代替C语言中的字符数组或字符串指针。
使用string类需要文件包含: #include <string>
1.2字符串的构造方法
- string s; //空串
- string s=“nefuer”;//利用常量字符串构造字符串
- string t = s;//利用已有的字符串对象赋值
- string (3, ‘a’);//”aaa” string (“china”,1,3);//”hin”
- string str3 = s+ t;
1.3字符串的基本操作
1.3.1输入
C++中的输入大致有6种方法:cin,cin.get(),cin.getline(),gets(),getchar()
cin
用法一:最常用的方法,接收一个字符串,无论是string还是char a[10],都是一样,但是遇到“空格”,“TAB”,"回车"都结束。#include<iostream> #include<string> using namespace std; int main() { string a, b; cin >> a >> b; cout << a << endl; cout << b << endl; return 0; }
cin.get()
用法一:cin.get(字符变量名)可以用来接收字符
#include<iostream> #include<string> using namespace std; int main() { char ch; ch = cin.get();//或者是cin.get(ch); cout << ch; return 0; }
用法二:cin.get(字符数组名,接收字符个数),用来接收一行字符串(可以接收空格),这个最大的用途是可以定量的接收字符的个数(但是要注意,如果定义的数组的个数是20,则实际上最大接收19个字符(可以小于19),还要加上'\0')
这个方法只能正针对于是字符数组,不能使用string来输入。
#include<iostream> #include<string> using namespace std; int main() { char a[20]; //string a;报错 cin.get(a, 20); cout << a; return 0; }
cin.getline()
可以接收空格,并且输出。浅显的用法其实和cin.get()差不多。(也不能使用string来进行输入)#include<iostream> #include<string> using namespace std; int main() { char a[20]; cin.getline(a, 20); cout << a; return 0; }
更加深层的用法其实就是cin.getline()的原型,这个函数本来有三个参数,分别是字符串的位置,接受个数,结束字符。
如果将例子中cin.getline()改为cin.getline(m,5,'a');当输入jlkjkljkl时输出jklj,输入jkaljkljkl时,输出jk
当用在多维数组中的时候,也可以用cin.getline(m[i],20)之类的用法:
#include<iostream> #include<string> using namespace std; int main () { char m[3][20]; for(int i=0;i<3;i++){ cout<<"\n请输入第"<<i+1<<"个字符串:"<<endl; cin.getline(m[i],20); } cout<<endl; for(int j=0;j<3;j++) cout<<"输出m["<<j<<"]的值:"<<m[j]<<endl; return 0; }
getline()
接收一个字符串,可以接收空格并输出,不过要包含#include<string>
这也就弥补了之前cin.getline()和cin.get()的不能读取string的一个小的弊端
这里还要将这个写法稍微改正一下getline(cin,字符串数组名);用法一:一行,默认换行符结束
#include<iostream> #include<string> using namespace std; int main() { string s; getline(cin,s); cout << s; return 0; }
用法二://一行或者多行,以第三个参数结束
#include<iostream> #include<string> using namespace std; int main() { string s; getline(cin,s,'.'); cout << s; return 0; }
gets()
接收一个字符串,可以接收空格并且输出,需要包含#include<string>
但是这个函数有些奇葩的是,这个函数必须要包含头文件string,但是这个函数却不能直接对变量string来进行赋值。#include<iostream> #include<string> using namespace std; int main() { char s[10]; gets_s(s); cout << s; return 0; }
这个函数不安全
getchar()
获取单个字符,需要包含#include<string>。
这个函数尽量少用#include<iostream> #include<string> using namespace std; int main() { char ch; ch = getchar(); cout << ch; return 0; }
适合用来吃回车
1.3.2输出
setw()函数
C++中的setw()函数是在输出操作中使用的字段宽度设置,此函数的作用是:设置输出的域宽,n表示字段宽度。
当后面紧跟着的输出字段长度小于n的时候,在该字段前面用空格补齐;当输出字段长度大于n时,全部整体输出。
包含在头文件为#include <iomanip>中,其中io代表输入输出,manip是manipulator(操纵器)的缩写iomanip的作用
#include <iostream> using namespace std; #include <iomanip> int main() { cout << 123456789 << endl; cout << setw(2) << 123 << setw(7) << 456789 << endl; return 0; }
其他常见的iomanip标准库函数
setfill(n) 设置字符填充,c可以是字符常或字符变量
setprecision(n) 设置浮点数的有效数字为n位 setw(n) 设置字段宽度为n位 #include <iostream> #include <iomanip> // 包含设置格式的库 using namespace std; int main() { char c = '#'; double num = 3.14159265359; cout << setfill(c) << setw(10) << "hello" << endl; // 输出 "####hello" cout << fixed << setprecision(3) << num << endl; // 输出 "3.142" cout << setfill('0') << setw(6) << 42 << endl; // 输出 "000042" return 0; }
二、字符串的操作
2.1字符串的基本操作
字符串的基本操作 string s,t;
- 赋值:s=“pear”; t=s;
- 关系判断: s<t
- s==t
- 连接: s+t 添加:
- s+=t;
- s.append(t);
- s.push_back(‘a’);
- 交换:swap()
- s.swap( t )
- 长度:s.length() s.size( )
2.2字符串的常见操作
2.2.1字符串的访问
- 使用下标运算符[]。例如:
string str = "Hello"; cout << str[0] << endl; // 输出 H
- 使用at()函数。例如:
string str = "Hello"; cout << str.at(0) << endl; // 输出 H
- substr()函数获取子串
string substr(int pos=0, int len=string::npos) const; 获取从下标pos开始的len个字符形 成子串,如果省略len或者pos+len超出字符串长度则默认到最后一个字符。
string str = "Hello World"; string substr = str.substr(0, 5); // 获取 "Hello"
2.2.2字符串的查找
1.find()函数用于在string字符串中查找子字符串第一次出现的位置。
size_t find (const string& str, size_t pos = 0) const;
第一个参数为待查找的子字符串,它可以是string字符串,也可以是C风格的字符串。第二个参数为查找的起始位置,默认值为0。
string str = "Hello World"; int index = str.find("World"); // 获取 6
2.rfind()函数用于在字符串中从后向前查找子串(字符)首次出现位置(rfind从后向前逆向查,但匹配是正向匹配的)
size_t rfind (const string& str, size_t pos = npos) const;
第一个参数为待查找的子字符串,它可以是string字符串,也可以是C风格的字符串。第二个参数为查找的起始位置,默认值为npos。
string str = "Hello World"; int index = str.rfind("o"); // 获取 7
3.s.find_first_of(str)和s.find_last_of(str)
找到目标字符在字符串中第一次出现和最后一次出现的位置
#include<bits/stdc++.h> #include<iostream> using namespace std; int main(){ string s,c; s="baaaaab"; c="b"; cout<<"first index:"<<s.find_first_of(c)<<endl; cout<<"last index:"<<s.find_last_of(c)<<endl; }
4查找目标字符串在字符串出现的总次数
#include<bits/stdc++.h> #include<iostream> using namespace std; int main(){ // 定义两个字符串变量s和c,分别存储原始字符串和子串 string s,c; // 定义两个整数变量index和sum,分别存储当前匹配的位置和总匹配次数 int index,sum; // 初始化index和sum为0 index=0; sum=0; // 使用while循环读入s和c,直到输入结束 while(cin>>s>>c){ // 使用while循环在s中查找c,使用find函数返回匹配的位置,如果没有匹配,返回string::npos while((index=s.find(c,index))!=string::npos){ // 输出当前匹配的次数和位置 cout<<"sum: "<<sum+1<<" index: "<<index<<endl; // 更新index为当前匹配位置加上c的长度,以避免重复匹配 index+=c.length(); // 更新sum为当前匹配次数加一 sum++; } // 输出最终的匹配次数 cout<<sum<<endl; } // 返回0表示程序正常结束 return 0; } /* banana na */
string::npos是一个常量静态成员值,它是size_t类型的元素能表示的最大值12。它实际上表示字符串的结尾
2.2.3字符串插入
字符串insert( )函数
在原串下标为pos的字符前插入字符串str
basic_string& insert (size_type pos, const basic_string& str);
str从下标为pos1开始数的n个字符插在原串下标为pos的字符前
basic_string& insert (size_type pos, const basic_string& str, size_type pos1, size_type n);
在原串下标为pos的字符前插入n个字符c
basic_string& insert (size_type pos, size_type n, char c);
举例
#include<iostream> using namespace std; int main() { string str="hello"; string s="Hahah"; str.insert(1,s);//在原串下标为1的字符e前插入字符串s cout<<str<<endl; string str1="hello"; char c='w'; str1.insert(4,5,c);//在原串下标为4的字符o前插入5个字符c cout<<str1<<endl; string str2="hello"; string s2="weakhaha"; str2.insert(0,s2,1,3);//将字符串s2从下标为1的e开始数3个字符,分别是eak,插入原串的下标为0的字符h前 cout<<str2<<endl; return 0; }
2.2.4替换字符串的子串:replace( ) 函数
将下标pos开始的len个字符替换为特定字符串str
string& replace (size_t pos, size_t len, const string& str);
将迭代器beg和end中间的字符替换为str
string& replace (iterator beg, iterator end, const string& str);#include <iostream> #include <string> using namespace std; int main() { // 创建一个字符串对象 string s = "Hello world!"; // 调用第一个函数,将下标为6开始的5个字符替换为"China" s.replace(6, 5, "China"); // 输出替换后的字符串 cout << s << endl; // Hello China! // 调用第二个函数,将迭代器s.begin()和s.begin()+5之间的字符替换为"Hi" s.replace(s.begin(), s.begin() + 5, "Hi"); // 输出替换后的字符串 cout << s << endl; // Hi China! return 0; }
2.2.5删除字符串中的子串:erase( )函数
删除字符串中的子串:erase( )函数
删除迭代器pos指向的元素 string& erase(iterator pos);
删除迭代器pos开始的len个字符 string& erase (iterator pos=0,size_t len=npos);
删除迭代器first到last中间字符 string.erase(iterator first,iterator last);
#include <iostream> #include <string> using namespace std; int main() { // 创建一个字符串对象 string s = "Hello world!"; // 调用第一个函数,删除下标为6开始的5个字符 s.erase(6, 5); // 输出删除后的字符串 cout << s << endl; // Hello ! // 调用第二个函数,删除迭代器s.begin()+5指向的字符 s.erase(s.begin() + 5); // 输出删除后的字符串 cout << s << endl; // Hello! // 调用第三个函数,删除迭代器s.begin()+2和s.end()-1之间的字符 s.erase(s.begin() + 2, s.end() - 1); // 输出删除后的字符串 cout << s << endl; // He! return 0; }
2.2.6string与C风格字符串的转换
c_str( )函数
c_str ()函数是string类的一个成员函数,它返回一个指向正规C字符串的指针常量,内容与本string串相同
#include <iostream> #include <string> using namespace std; int main() { // 创建一个字符串对象 string s = "Hello world!"; // 调用c_str ()函数,返回一个指向C字符串的指针 const char* c = s.c_str(); // 输出C字符串 cout << c << endl; // Hello world! return 0; }
2.3string对象的STL常用算法
string 对象也可以看作一个顺序容器,它支持随机访问迭代器,也有 begin 和 end 等成员函数。STL 中的许多算法也适用于 string 对象。 计数,查找,删除,排序等操作都可以利用STL算法来完成。
2.3.1计数
count( ): 查找值value在容器中的个数,它可以用于任何支持迭代器的容器,如vector,list,set,map等。它的用法是:
count(first, last, value);
其中first和last是容器的首尾迭代器,value是要查找的元素。它的返回值是一个整数,表示value在容器中出现的次数
#include <iostream> #include <string> #include <algorithm> using namespace std; int main() { string s = "hello world"; // 定义一个string对象 int n = count(s.begin(), s.end(), 'l'); // 查找'l'在s中的个数 cout << n << endl; // 输出3 return 0; }
2.3.2排序与反序操作
sort( ):排序
sort(s.begin( ) , s.end( ) );
//对字符串中字符进行升序排序 reverse( ):
反序,将序列 [beg , end)的元素在原容器中反序
reverse(iterator beg,iterator end);
reverse(s.begin( ) , s.end( ) ); //对字符串进行反序
#include <iostream> #include <string> #include <algorithm> using namespace std; bool comp(char a, char b) { // 定义一个比较函数,按照字母表顺序的逆序比较字符 return a > b; } int main() { string s = "hello world"; // 定义一个string对象 sort(s.begin(), s.end()); // 对s中的字符进行升序排序 cout << s << endl; // 输出 dehllloorw sort(s.begin(), s.end(), comp); // 对s中的字符按照comp函数指定的规则进行排序 cout << s << endl; // 输出 wroollldhhe reverse(s.begin(), s.end()); // 将s中的字符反转 cout << s << endl; // 输出 ehhdllloorw return 0; }
2.3.3删除元素remove( )|remove_if( )
remove(first, last, value); // 删除[first, last)区间内等于value的元素,并返回新的超尾值的迭代器
remove(iterator beg, iterator end, value);
注意:remove函数并不是真的删除元素,它只是通过迭代器的指针向前移动来删除,将没有被删除的元素放在容器前面,并返回一个指向新的超尾值的迭代器,如果需要删除元素,需要结合对应容器的earse函数。
remove_if( )函数:删除容器中满足fun函数中条件的元素,效果等同remove函数,可以用来删除多个元素。
remove_if(iterator beg, iterator end, fun);
2.3.4替换元素 replace():
replace()
是字符串的一个方法,它可以用来替换字符串中的某些字符或子串。replace(iterator beg, iterator end, oldvalue, newvalue);
举例
#include <iostream> #include <string> using namespace std; int main() { string s = "Hello World"; // 定义一个string对象 s.replace(0, 5, "Hi"); // 用"Hi"替换从0开始长度为5的子串 cout << s << endl; // 输出 Hi World s.replace(s.begin(), s.begin() + 3, "Bye"); // 用"Bye"替换从迭代器s.begin()到s.begin() + 3的子串 cout << s << endl; // 输出 Bye World s.replace(4, 5, "Bye", 0 ,3); // 用"Bye"的从0开始长度为3的子串替换从4开始长度为5的子串 cout << s << endl; // 输出 Bye Bye s.replace(0 ,3 , "Hello"); // 用C字符串"Hello"替换从0开始长度为3的子串 cout << s << endl; // 输出 Hello Bye s.replace(s.begin(), s.begin() + 5 , "Hi"); // 用C字符串"Hi"替换从迭代器s.begin()到s.begin() + 5的子串 cout << s << endl; // 输出 Hi Bye s.replace(0 ,2 , "Hello", 3); // 用C字符串"Hello"的前3个字符替换从0开始长度为2的子串 cout << s << endl; // 输出 Hel Bye s.replace(s.begin(), s.begin() +3 , "Hi",2); // 用C字符串"Hi"的前2个字符替换从迭代器s.begin()到s.begin() +3 的子串 cout << s << endl; // 输出 Hi Bye s.replace(0 ,2 ,3 ,'*'); // 用3个字符'*'替换从0开始长度为2的子串 cout << s << endl; // 输出 *** Bye s.replace(s.begin(), s.end(), "Hello World"); // 用"Hello World"替换从迭代器s.begin()到s.end()的子串,即整个字符串 cout << s << endl; // 输出 Hello World return 0; }