目录
编辑
容器string中的一些函数
1.capacity()
2.reserve()
3.resize()
4.push_back()与append()
5.find系列函数
容器string中的一些函数
1.capacity()
capacity是string当中表示容量大小的函数。但是string开空间时是如何开的呢?现在就来看一下。先写这样一段程序:
int main() { string s ; int old = s.capacity(); cout << "原来的容量:"<<old << endl; for (int i = 0;i < 100;i++) { s += 'c'; if (s.capacity() != old) { cout << "扩容:" << s.capacity() << endl; old = s.capacity(); } } return 0; }
结果:
在这里可以看到除了第一次扩容以后,其它的扩容都是1.5倍扩容。可以说在vs环境下string扩容都是1.5倍扩容。但是为什么第一次扩容不是1.5倍扩容呢?这是因为在vs中要处理一些内存对齐的问题。所以,第一次扩容才不是1.5倍扩容。
2.reserve()
我们都知道,扩容是一件非常耗效率的事情。所以在程序中我们总是要去避免掉扩容。那我们有什么好办法去防止扩容呢?这还真有办法,就是使用reserve()函数。但是这个办法要在你知道大概要开多少空间的情况下使用。比如上面的程序,我知道要开一百个字节的空间。所以我就这样操作:
int main() { string s ; int old = s.capacity(); cout << "原来的容量:"<<old << endl; s.reserve(100);//预开一百个字节的空间 for (int i = 0;i < 100;i++) { s += 'c'; if (s.capacity() != old) { cout << "扩容:" << s.capacity() << endl; old = s.capacity(); } } return 0; }
结果:
这样便有效的避免了多次扩容。
这里要注意的一点是,reverse()函数是不能够缩小空间的。
3.resize()
resize()函数相当于是reserve()加上初始化。resize()函数有两种形式:1.resize(size),2.resize(size,char)。第一种形式的参数只有要开的长度,于是resize()会默认初始化开辟的空间里的数据为'\0'。第二种形式要传的参数便是要开辟的空间的大小与初始化这段空间的值。并且这个函数会自动扩容。如下列程序:
string s ; s.resize(100); cout << s << endl; return 0;
结果:
这时因为'\0'不会显示出来。
再比如下列程序:
string s ; s.resize(100,'c'); cout << s << endl; return 0;
结果:
4.push_back()与append()
push_back()函数是干嘛的相信大家都懂。这个函数实现的便是一个尾插的功能,实现的就是一个一个字符的尾插。比如我要将x插入到s中:
string s ; s.resize(3,'c'); s.push_back('x'); cout << s << endl; return 0;
结果:
但是如果我要插入字符串xxxxx呢?这时push_back()可解决不了了。此时就得append()上场了:
string s ; s.resize(3,'c'); s.append("xxxxx"); cout << s << endl; return 0;
结果:
5.find系列函数
find(char*/char):这个函数实现的功能是从字符串的头往尾找。找到了要找的字符串便返回字符所在的下标。比如我要找一个.cpp文件的后缀:
int main() { string s = "text.cpp"; int i = s.find('.'); cout << s.substr(i) << endl; }
结果:
成功找到。
但是,如果现在我要找的是text.cpp.zip的文件后缀呢?此时就得rfind()上场了,rfind(char*/char) :
这个函数实现的功能是和find()函数相反的。它实现的功能是从后往前查找字符,找到字符后也是返回字符所在下标。对于找text.cpp.zip文件的后缀,代码如下:
int main() { string s = "text.cpp.zip"; int i = s.rfind('.'); cout << s.substr(i) << endl; }
结果:
再比如说我要找到一个网址的协议,域名,资源名该怎么找呢?比如这个网址:
https://mp.csdn.net/mp_blog/creation/editor?spm=1011.2415.3001.6217
这个网址的协议是:https
域名是:mp.csdn.net
资源是:/mp_blog/creation/editor?spm=1011.2415.3001.6217
我们该怎么办呢?其实挺简单的,代码如下:
string s = "https://mp.csdn.net/mp_blog/creation/editor?spm=1011.2415.3001.6217"; int begin = 0; int end = 0; end = s.find(":"); cout << "协议:"<<s.substr(begin, end) << endl; begin = end + 3; end = s.find("/",begin); cout <<"域名:"<< s.substr(begin, end) << endl; cout << "资源名:"<<s.substr(end) << endl;
关键是要调整寻找的范围。比如第一次找到协议以后,便跳过协议和"//"到后面去找。
find_first_of(char*/char):这个函数能实现找到要找的字符串里的任何一个字符并返回该字符的下标。如:
string s = "https://mp.csdn.net/mp_blog/creation/editor?spm=1011.2415.3001.6217"; cout <<"修改前:"<< s << endl; std::size_t found = s.find_first_of("aeiou"); while (found != std::string::npos) { s[found] = '*'; found = s.find_first_of("aeiou", found + 1); } cout <<"修改后:"<< s << endl;
find_last_of(char*/char):功能与find_firsy_of一样,但是顺序是从后往前找。