目录
一.构造函数
函数列表:
string(); | 构造一个空的字符串(无参构造) |
string(const string& str); | 拷贝构造 |
string(const string& str, size_t pos,size_t len=npos); | 用一个字符串从pos位置开始后len个字符来拷贝构造 |
string(const char* s); | 用一个C-string来构造字符串 |
string(const char* s, size_t n); | 用一个C-string的前n个字符来构造字符串 |
string(size_t n, char c); | 用n个字符c构造字符串 |
代码演示 :
include<string>
include<iostream>
using namespace std;
int main(){
//string();
string s1;//无参构造
//string(const char* s);
string s2("hello world");//用常字符串创建字符串对象
//string(const char* s, size_t n);
string s3("hello world",5);//用常字符串的前五个字符构造字符串
//string(const string& str);
string s4(s2);//拷贝构造
//string(const string& str, size_t pos,size_t len=npos);
string s5(s2,3,4);//用s2位置3后4个字符来拷贝构造
//string(size_t n, char c);
string s6(5,'d');//用5个字符'd'构造字符串
cout<<s1<<endl;//
cout<<s2<<endl;//hello world
cout<<s3<<endl;//hello
cout<<s4<<endl;//hello world
cout<<s5<<endl;//lo w
cout<<s6<<endl;//ddddd
return 0;
}
注意事项:
(1)用无参构造创造对象一般直接 【string s;】后不加括号,为了防止与无形参列表的函数声明冲突【string s();】。
(2)size_t 类型指无符号类型。
(3)npos 是静态常量,类型是size_t, 具有最大可能值,此值在字符串的成员函数中用作 len(或 sublen)参数的值时,表示“直到字符串结束”。
二.容量操作函数
函数列表:
size | size_t size() const; | 返回有效字符长度 |
length | size_t length() const; | 返回有效字符长度 |
resize | void resize(size_t n); | 修改有效长度为n,超出部分用空字符('\0')填充 |
void resize(size_t n, char c); | 修改有效长度为n,超出部分用字符c填充 | |
capacity | size_t capacity() const; | 返回当前容器的容量大小 |
reserve | void reserve(size_t n=0); | 扩容到大小为n(或更大) 若n小于原容量,维持原容量大小不变 |
clear | void clear(); | 删除所有字符,使其变为空串 |
empty | bool empty() const; | 判断是否为空串 |
代码演示:
#include<string>
#include<iostream>
using namespace std;
int main(){
string s("hello world");
//void resize(size_t n, char c);
s.resize(20,'c');//修改有效长度为20,超过部分用'c'填充
//void resize(size_t n);
s.resize(30);//修改有效长度为30,超过部分用'\0'填充
//void reserve(size_t n=0);
s.reserve(50);//扩充容量为50以上
cout<<s<<endl;
size_t capacity() const;
cout<<"capacity:"<<s.capacity()<<endl;//返回容量大小
//size_t size() const;
cout<<"size:"<<s.size()<<endl;//返回有效字符串长度
//size_t length() const;
cout<<"length:"<<s.length()<<endl;//返回有效字符串长度
//bool empty() const;
cout<<s.empty()<<endl;//判断是否为空 0
//void clear();
s.clear();//清空为空字符串
//bool empty() const;
cout<<s.empty()<<endl;//1
return 0;
}
注意事项:
(1)size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
(2)clear()只是将string中有效字符清空,不改变底层空间大小。
(3)resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
(4)reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。
三.元素访问函数
函数列表:
operator [ ] | char& operator [](size_t pos); | 返回pos位置字符的引用 |
const char& operator[](size_t pos) const; | ||
back | char& back(); | 返回最后一个字符的引用 |
const char& back() const; | ||
front | char& front(); | 返回第一个字符的引用 |
const char& front() const; |
代码演示:
#include<string>
#include<iostream>
using namespace std;
int main(){
string s("hello world");
cout<<"s[4]:"<<s[4]<<endl;
cout<<"back():"<<s.back()<<endl;
cout<<"front():"<<s.front()<<endl;
return 0;
}
注意事项:
传引用返回可直接对值进行修改
#include<string> #include<iostream> using namespace std; int main(){ string s1("aaa"); s1[1]++; cout<<s1<<endl;//aba s1.back()++; cout<<s1<<endl;//abb s1.front()++; cout<<s1<<endl;//bbb return 0; }
四.修改函数
函数列表:
operator += | string& operator +=(const string& str); | 在字符串末尾插入字符串 |
string& operator +=(const char* s); | 在字符串末尾插入C-string | |
string& operator +=(char c); | 在字符串末尾插入单个字符 | |
push_back | void push_back(char c); | 将字符c插入字符串末尾 |
pop_back | void pop_back(); | 删除最后一个字符 |
append | string& append(const string& str); | 在末尾插入字符串 |
string& append(const string& str, size_t subpos, size_t sublen); | 在末尾插入str从subpos位置往后sublen个字符 | |
string& append(const char* s); | 在末尾插入C-string | |
string& append(const char* s,size_t n); | 在末尾插入s的前n个字符 | |
string& append(size_t n,char c); | 在末尾插入n个字符c | |
insert | string& insert(size_t pos, const string& str); | 在pos前插入str |
string& insert(size_t pos, const string& str,size_t subpos, size_t sublen); | 在pos前插入str从subpos位置往后sublen个字符 | |
string& insert(size_t pos, const char* s); | 在pos前插入C-string | |
string& insert(size_t pos, const char* s,size_t n); | 在pos前插入s的前n个字符 | |
string& insert(size_t pos, size_t n,char c); | 在pos前插入n个字符c | |
erase | string& erase(size_t pos,size_t len=npos); | 从pos位置开始删除len个字符 |
代码演示:
//+=的用法
#include<iostream>
#include<string>
using namespace std;
int main(){
string s1("abcde");
string s2("abcde");
//string& operator +=(char c);
s1+='f';//尾部插入单个字符'f'
cout<<s1<<endl;//abcdef
s1="abcde";
//string& operator +=(const string& str);
s1+=s2;//尾部插入字符串s2
cout<<s1<<endl;//abcdeabcde
s1="abcde";
//string& operator +=(const char* s);
s1+="abcde";//尾部插入C-string
cout<<s1<<endl;//abcdeabcde
return 0;
}
//push_back()的用法
#include<iostream>
#include<string>
using namespace std;
int main(){
string s1("abcd");
char ch='e';
//void push_back(char c);
s1.push_back(ch);//尾部插入单个字符ch
s1.push_back('f');//尾部插入单个字符'f'
cout<<s1<<endl;//abcdef
return 0;
}
//pop_back的用法
#include<iostream>
#include<string>
using namespace std;
int main(){
string s1("abcdef");
//void pop_back();
s1.pop_back();//尾部删除单个字符
cout<<s1<<endl;//abcde
return 0;
}
//append()用法
#include<iostream>
#include<string>
using namespace std;
int main(){
string s1("abcde");
string s2("abcde");
//string& append(const string& str);
s1.append(s2);//尾部插入字符串s2
cout<<s1<<endl;//abcdeabcde
s1="abcde";
//string& append(const string& str, size_t subpos, size_t sublen);
s1.append(s2,3,2);//尾部插入字符串s2从位置3开始向后2个字符
//注:若写入字符个数大于写入位置后的长度,表示直到字符串结束
cout<<s1<<endl;//abcdede
s1="abcde";
//string& append(const char* s);
s1.append("abcde");//尾部插入C-string
cout<<s1<<endl;//abcdeabcde
s1="abcde";
//string& append(const char* s,size_t n);
s1.append("abcde",3);//尾部插入C-string的前3个字符
//注:若写入字符个数大于字符串的长度,表示直到字符串结束
cout<<s1<<endl;//abcdeabc
s1="abc";
//string& append(size_t n,char c);
s1.append(3,'d');//尾部插入3个字符'd'
cout<<s1<<endl;//abcddd
return 0;
}
//insert()用法
#include<iostream>
#include<string>
using namespace std;
int main(){
string s1("abcde");
string s2("abc");
//string& insert(size_t pos, const string& str);
s1.insert(3,s2);//在位置3前(d前)插入字符串s2
cout<<s1<<endl;//abcabcde
s1="abcde";
//string& insert(size_t pos, const string& str,size_t subpos, size_t sublen);
s1.insert(3,s2,1,2);//在位置3前(d前)前插入字符串s2从位置1开始向后2个字符
//注:若写入字符个数大于写入位置后的长度,表示直到字符串结束
cout<<s1<<endl;//abcbcde
s1="abcde";
s1.insert(3,"abcde");//在位置3前(d前)前插入C-string
cout<<s1<<endl;//abcabcdede
s1="abcde";
s1.insert(3,"abcde",3);//在位置3前(d前)前插入C-string的前3个字符
//注:若写入字符个数大于字符串的长度,表示直到字符串结束
cout<<s1<<endl;//abcabcde
s1="abcde";
s1.insert(3,'d',3);//在位置3前(d前)前插入3个字符'd'
cout<<s1<<endl;//abcdddde
return 0;
}
#include<iostream>
#include<string>
using namespace std;
int main(){
//erase()用法
string s1("abcde");
s1.erase(1,3);//从位置1开始删除3个字符
cout<<s1<<endl;//ae
s1="abcde";
s1.erase(1);//不写字符个数默认为npos,表示直到字符串结束
cout<<s1<<endl;//a
return 0;
}
注意事项:
(1)在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
(2) 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。可以减少扩容次数,提高效率。
五.字符串操作函数
函数列表:
c_str | const char* c_str() const; | 返回C-string |
substr | string substr(size_t pos=0, size_t len=npos) const; | 截取字符串从pos位置开始向后n个字符 |
find | size_t find(const string& str, size_t pos=0) const; | 在当前字符串中从pos位置开始搜索str的匹配项,返回第一个匹配项的位置下标 |
size_t find(const char* s,size_t pos=0) const; | 在当前字符串中从pos位置开始搜索C-string的匹配项,返回第一个匹配项的位置下标 | |
size_t find(const char*s, size_t pos,size_t n) const; | 在当前字符串中从pos位置开始搜索C-string前n个字符的匹配项,返回第一个匹配项的位置下标 | |
size_t find(char c, size_t pos=0) const; | 在当前字符串中从pos位置开始搜索字符c的匹配项,返回第一个匹配项的位置下标 | |
compare | int compare(const string& str) const; | 与另一个字符串进行比较 |
int compare(size_t pos, size_t len,const string& str) const; | 当前字符串从pos位置开始向后长度为len的子串与另一字符串进行比较 | |
int compare(size_t pos, size_t len,const string& str, size_t subpos, size_t sublen) const; | 当前字符串从pos位置开始向后长度为len的子串与另一字符串从subpos 位置开始长度为sublen的子串进行比较 | |
int compare(const char* s) const; | 与C-string比较 | |
int compare(size_t pos, size_t len , const char* s) const; | 当前字符串从pos位置开始向后长度为len的子串与C-string比较 | |
int compare(size_t pos, size_t len , const char* s,size_t n) const; | 当前字符串从pos位置开始向后长度为len的子串与C-string的前n个字符比较 |
代码演示:
//c_str
#include<string>
#include<iostream>
using namespace std;
int main(){
//const char* c_str() const;
string s("hello world");
printf("%s\n", s);//乱码
printf("%s\n", s.c_str());//hello world
return 0;
}
//substr
#include<string>
#include<iostream>
using namespace std;
int main(){
//string substr(size_t pos=0, size_t len=npos) const;
string s("hello world");
string s1 = s.substr(0, 5);
cout << s1 << endl;//hello
return 0;
}
//find
#include<string>
#include<iostream>
using namespace std;
int main(){
string s1("hello world");
string s2("llo");
//size_t find(const string & str, size_t pos = 0) const;
cout << s1.find(s2, 3) << endl;//在s1位置3后(第二个l后)搜索s2,没找到返回nops
cout << s1.find(s2) << endl;//在s1中搜索s2,找到返回下标2,不写pos默认从头开始
//size_t find(const char* s,size_t pos=0) const;
cout << s1.find("wor", 3) << endl;//在s1位置3后(第二个l后)搜索"wor",找到返回下标6
cout << s1.find("wor") << endl;//在s1中搜索"wor",找到返回下标6,不写pos默认从头开始
//size_t find(const char*s, size_t pos,size_t n) const;
cout << s1.find("worqq", 3, 3) << endl;//在s1位置3后(第二个l后)搜索"worqq"的前三个字符"wor",找到返回下标6
//size_t find(char c, size_t pos=0) const;
cout << s1.find('l', 4) << endl; //在s1位置4后(o后)搜索字符'l',找到返回下标9
cout << s1.find('l') << endl;//在s1中搜索字符'l',找到返回下标2,不写pos默认从头开始
return 0;
}
//compare
#include<string>
#include<iostream>
using namespace std;
int main(){
string s1("aaaaa");
string s2("bbbbb");
//int compare(const string& str) const;
cout << s1.compare(s2) << endl;//s1与32比较
//int compare(size_t pos, size_t len, const string & str) const;
cout << s1.compare(2, 2, s2) << endl;//s1从位置2开始向后2个字符的子串与s2比较
//int compare(size_t pos, size_t len, const string & str, size_t subpos, size_t sublen) const;
cout << s1.compare(2, 2, s2, 2, 3) << endl;//s1从位置2开始向后2个字符的子串与s2从位置2开始向后3个字符的子串比较
//int compare(const char* s) const;
cout << s1.compare("qqqqq") << endl;//s1与C-string比较
//int compare(size_t pos, size_t len , const char* s) const;
cout << s1.compare(2, 2, "qqqqq") << endl;//s1从位置2开始向后2个字符的子串与C-string比较
//int compare(size_t pos, size_t len , const char* s,size_t n) const;
cout << s1.compare(2, 2, "qqqqq", 3) << endl;s1从位置2开始向后2个字符的子串与C-string前3个字符比较
return 0;
}
注意事项:
compare比较规则:
(1)从前往后一个一个字符进行比较;
(2)不相等的第一个字符的值小则该字符串小;
例如:"acdq"与"acke"d的字典序小于k,则"acdq"<"acke"
(3)若所有字符都相等则字符串长度短的小;
例如:"acdq"与"acd"前三个字符串都相等,但后者比前者短,则"acdq">"acd"
(4)根据字典序进行比较;
compare返回值:
(1)等于返回0;
(2)小与则返回<0的值;
(3)大于则返回>0的值;
find使用说明:
在使用find时未找到会返回npos,将npos强转为int类型后的值为-1,因此在使用find时可将其强转为int类型与0进行比较,<则表示未找到。
#include<string> #include<iostream> using namespace std; int main(){ string s1("hello world"); string s2("ok"); string s3("llo"); if ((int)s1.find(s2) < 0) { cout << "未找到" << endl; } else { cout << "找到了" << endl; } if ((int)s1.find(s3) < 0) { cout << "未找到" << endl; } else { cout << "找到了" << endl; } return 0; }
六. 运算符重载
函数列表:
string中支持的运算符:
(1)< > == ,符合为true,不符合为false,按字典序比较;
(2)<< >>,流插入,流提取
(3)= +=;
(4)[ ];
(5)+;
注意事项:
(1)<< 支持流插入因此string可以直接 cout<<str 来进行输出;
(2)>> 流提取以空格做分隔符(会覆盖以前的内容)cin>>str ,若要提取整行文字使用getline(也会覆盖);(看下方详解)
(3)尽量少使用+,值传递,拷贝构造效率低。
getline :
(1) | istream& getline (istream& is, string& str, char delim); | 从 is 中提取字符并将其存储到 str 中,直到找到分隔字符 delim 或换行符“\n”)。 |
---|---|---|
(2) | istream& getline (istream& is, string& str); |
#include<string>
#include<iostream>
using namespace std;
int main(){
string s1("aaa");
getline(cin, s1);//以'/n'为分隔符,我会在此输入abcd efg
cout << s1 << endl;//abcd efg
getline(cin, s1, 'f');//以'f'或'/n'为分隔符,我会在此输入abcd efg
cout << s1 << endl;//abcd e
return 0;
}
七.遍历方法
1.[ ]
#include<string>
#include<iostream>
using namespace std;
int main(){
string s("hello world");
int i = 0;
while (i < s.size()) {
cout << s[i++];
}
cout << endl;
return 0;
}
2.迭代器
#include<string>
#include<iostream>
using namespace std;
int main(){
string s("hello world");
string::iterator it = s.begin();
while (it != s.end()) {
cout << *(it++);
}
cout << endl;
return 0;
}
3.范围for
#include<string>
#include<iostream>
using namespace std;
int main(){
string s("hello world");
for (auto c : s) {
cout << c;
}
cout << endl;
return 0;
}