引言:现在我们将正式踏入C++起飞阶段,C++语言自带的各种类能极大地简化我们所编写的代码的量,而我们今天要学的string就是其中之一。
更多有关C++的知识点详解可前往个人主页:计信猫
一,认识string
string其实很简单,我们可以简单地把它看成如下的代码实现的类:
class string
{
char* _str;//存储字符串
size_t _size = 0;//记录字符串的有效字符的个数
size_t _capacity = 0;//记录string的空间大小
};
所以显而易见,当我们想要储存一个字符串的时候,我们就可以使用string类来储存这个字符串,但前提是我们需要包含<string>的头文件。
二,string类对象的常见构造方式
1,string()
该方法构造的其实就是以空字符串来构造一个string类的对象。
2,string(const char* s)
有了这个方式,所以我们就可以将字符串的首元素的地址传给string,然后构造string类的对象,具体的方式如下:
int main()
{
const char* str = "hello";
string s1(str);
string s2("hehe");
return 0;
}
3,string(size_t n,char c)
这样的string类的构造方式比较少见,它的意思是使用n个字符c来构成一个字符串,再以该字符串构造string类的对象。
int main()
{
string s3(3, 'h');//以字符串"hhh"来构造s3
return 0;
}
4,string(string const& s)
该方式我们就见怪不怪了,这里就是利用了我们的拷贝构造函数来对我们的对象进行构造。
int main()
{
string s3(3, 'h');//以字符串"hhh"来构造s3
string s4(s3);//使用拷贝构造函数构造s4
return 0;
}
三,string类对象的容量的操作
1,size和capacity
当我们想要知道我们的string类对象的有效字符个数的大小时,我们就可以使用size,使用方式如下:
int main()
{
string s1("hhh");
int count = s1.size();//获取了s1中有效字符的个数
return 0;
}
而与之相同的,当我们想要知道s1的空间总大小的时候,我们就可以使用s1.capacity()来获取s1的总空间大小。
2,empty
empty意为空的,所以如果对象中字符串为空,则该函数会返回true,反之则会返回false。
3,clear
clear意为清除,当我们使用clear函数时,那么此时对象当中的字符串就会被完全清除,size会变为0,但是我们的空间总大小capacity并不会改变。
4,reserve
reserve函数会为string预留出空间的大小,相当于就是改变capacity的值,并且为string开出对应capacity的空间大小,但当我们reserve的值小于我们原本的capacity时,reserve不会改变容量大小。
所以我们可以理解为reserve只可以扩容,不可以缩容。
int main()
{
string s1("hhh");
s1.reserve(10);//将s1的总空间大小变为10
return 0;
}
5,resize
resize可以改变string中有效字符的个数,我们将其分为两个部分来讲。
Ⅰ,将size变大
那么此时我们就有两种方式:resize(size_t n) 与 resize(size_t n, char c),两者都可以将string的size变为n,但不一样的是,前者是使用‘0’来填充,而后者是使用字符c来进行填充。
Ⅱ,将size变小
当我们想要将size变小时,那就意味着原来的字符串会被删除一部分,而我们的底层总空间capacity并不会改变。
四,string类对象的访问和遍历
1,operator[]
在string类对象当中,我们就可以使用下标对字符串中某个特定位置的字符进行访问,我们就可以理解为将一个字符串拆开,然后一个一个地存放在字符数组当中了。
int main()
{
string s1("hhh");
char c = s1[1];//使用下标对s1进行访问
return 0;
}
2,迭代器begin+end
迭代器是我们新学的内容,在初级阶段我们就可以将它理解为一个指针,begin指向字符串的首元素地址,而end指向字符串结尾的下一个地址。那么我们使用迭代器进行string类对象的遍历代码如下:
int main()
{
string s1("hello world");
string::iterator it = s1.begin();//创建一个迭代器it来遍历s1
while (it != s1.end())
{
cout << *it;//打印
it++;
}
return 0;
}
那么代码一走,结果如下:
3,范围for
范围for也是一种遍历string的方法,它的底层逻辑其实也就是迭代器,所以,只要可以使用迭代器的地方,就可以使用范围for来遍历。而范围for的遍历方式如下:
int main()
{
string s1("hello world");
for (auto ch : s1)
{
cout << ch;
}
return 0;
}
其中auto的含义为自动,那么此时auto就会根据给ch赋值的变量的类型来自动变为对应的类型。
五,string类对象的修改操作
1,push_back
push_back函数的作用很简单,但也非常地常用,它可以在原string字符串的末尾再插入一个字符,试例如下:
int main()
{
string s1("hello world");
s1.push_back('a');//在字符串末尾添加一个字符a
for (auto ch : s1)//使用范围for进行打印
{
cout << ch;
}
return 0;
}
代码一走,结果如下:
2,append
append跟前面所学的push_back很相似,两者都是在字符串末尾进行添加,但是append则专门针对于字符串的添加,而不是单个字符的添加。
3,operator+=
operator+=这个字符串重载就比较常用了,它的作用也是连接一个字符串str在string字符串的末尾,而operator+=不仅可以针对单个字符,同时也可以针对一个字符串。
4,c_str
该函数则是用于返回string中的字符串的指针。
5,find
find(char c,size_t n)则是从string字符串的第n个位置开始向后寻找与c相同的字符,并立马停止且返回该字符的下标(n的缺省值为0),若没有找到,则会返回string::npos(一个很大的整数值)。
int main()
{
string s1("hello world");
int pos = s1.find('d');
return 0;
}
6,substr
substr(size_t pos,size_t len=npos)的作用是将从pos位置开始,长度为len的字符串内容取出,并且返回出来。当我们没有给len赋值时,系统则会默认将pos之后的所有字符取完并拿出来赋值。
int main()
{
string s1("hello world");
string s2;
s2 = s1.substr(6);//从s1中的下标为6的位置开始向后截取完
for (auto ch : s2)//使用范围for进行打印
{
cout << ch;
}
return 0;
}
那么代码一走,我们的程序结果如下:
六,string类非成员函数
1,operator<<和operator>>
想要打印或者输入string类中的字符串内容?很简单,C++已经帮我们字符串重载好了。当我们想要对某个string类的对象进行内容的输入和输出时,那么我们就可以直接使用<<和>>,示例如下:
int main()
{
string s1;
cin >> s1;
cout << s1;
return 0;
}
那么代码一走,我们输入"hello",结果如下:
2,getline
我们现在学习一个getline函数,它比operator>>更加的强大,getline函数只会在遇到换行时才会停止,并不会像operator>>一样遇到空格就停止,而它的使用示例如下:
int main()
{
string s1;
getline(cin, s1);//输入hello world
cout << s1 << endl;
return 0;
}
若我们想要getline函数在遇到特定的字符停下,我们则可以如下使用:
int main()
{
string s1;
getline(cin, s1,'*');//输入hello w*orld,使getline在遇到*时停下
cout << s1 << endl;
return 0;
}
七,结语
这是string类的基本介绍,看完了这些,那么相信你对string类也有了初步了解,能够正常的使用这个类了,接下来我会更新vector类的讲解,这个类也是一个C++中不可或缺的知识点,学习了它,那你写代码就会直接飞起来,尽情期待吧!